codexuse-cli 3.9.9 → 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 +163 -7
- 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 +2241 -1537
- package/dist/server/{open-BWXrZXJl.mjs → open-qeX1IlWK.mjs} +1 -1
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -16,8 +16,8 @@ import { fileURLToPath } from "node:url";
|
|
|
16
16
|
import * as readline$1 from "node:readline";
|
|
17
17
|
import readline from "node:readline";
|
|
18
18
|
import * as Net from "node:net";
|
|
19
|
-
import fs$1, { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
20
19
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
20
|
+
import fs$1, { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
21
21
|
import { EventEmitter } from "node:events";
|
|
22
22
|
import path, { join as join$1 } from "path";
|
|
23
23
|
import util from "node:util";
|
|
@@ -30084,7 +30084,7 @@ function make$17(get, mapInput, prefix) {
|
|
|
30084
30084
|
function fromEnv(options) {
|
|
30085
30085
|
const env = options?.env ?? {
|
|
30086
30086
|
...globalThis?.process?.env,
|
|
30087
|
-
...import.meta
|
|
30087
|
+
...import.meta.env
|
|
30088
30088
|
};
|
|
30089
30089
|
const trie = buildEnvTrie(env);
|
|
30090
30090
|
return make$17((path) => succeed$2(nodeAtEnv(trie, env, path)));
|
|
@@ -46235,377 +46235,1905 @@ var NetService = class NetService extends Service()("@t3tools/shared/Net/NetServ
|
|
|
46235
46235
|
}
|
|
46236
46236
|
};
|
|
46237
46237
|
//#endregion
|
|
46238
|
-
//#region src/
|
|
46239
|
-
|
|
46240
|
-
|
|
46241
|
-
|
|
46242
|
-
|
|
46243
|
-
|
|
46244
|
-
|
|
46245
|
-
|
|
46246
|
-
|
|
46247
|
-
|
|
46248
|
-
|
|
46249
|
-
|
|
46250
|
-
|
|
46251
|
-
|
|
46252
|
-
static {
|
|
46253
|
-
this.layerTest = (cwd, statedir) => effect(ServerConfig$1, gen(function* () {
|
|
46254
|
-
return {
|
|
46255
|
-
cwd,
|
|
46256
|
-
stateDir: statedir,
|
|
46257
|
-
mode: "web",
|
|
46258
|
-
autoBootstrapProjectFromCwd: false,
|
|
46259
|
-
logWebSocketEvents: false,
|
|
46260
|
-
port: 0,
|
|
46261
|
-
host: void 0,
|
|
46262
|
-
authToken: void 0,
|
|
46263
|
-
keybindingsConfigPath: (yield* Path$1).join(statedir, "keybindings.json"),
|
|
46264
|
-
staticDir: void 0,
|
|
46265
|
-
devUrl: void 0,
|
|
46266
|
-
noBrowser: false
|
|
46267
|
-
};
|
|
46268
|
-
}));
|
|
46238
|
+
//#region ../../packages/contracts/src/settings/chat-scrollback.ts
|
|
46239
|
+
const CHAT_SCROLLBACK_DEFAULT = 200;
|
|
46240
|
+
const CHAT_SCROLLBACK_MIN = 50;
|
|
46241
|
+
const CHAT_SCROLLBACK_MAX = 5e3;
|
|
46242
|
+
function clampChatScrollbackItems(value) {
|
|
46243
|
+
if (!Number.isFinite(value)) return 200;
|
|
46244
|
+
return Math.max(50, Math.min(CHAT_SCROLLBACK_MAX, Math.round(value)));
|
|
46245
|
+
}
|
|
46246
|
+
function normalizeChatHistoryScrollbackItems(value) {
|
|
46247
|
+
if (value === null) return null;
|
|
46248
|
+
if (typeof value === "number" && Number.isFinite(value)) return clampChatScrollbackItems(value);
|
|
46249
|
+
if (typeof value === "string") {
|
|
46250
|
+
const parsed = Number(value);
|
|
46251
|
+
if (Number.isFinite(parsed)) return clampChatScrollbackItems(parsed);
|
|
46269
46252
|
}
|
|
46270
|
-
|
|
46271
|
-
|
|
46272
|
-
const { join, resolve } = yield* Path$1;
|
|
46273
|
-
const { exists } = yield* FileSystem;
|
|
46274
|
-
const bundledClient = resolve(join(import.meta.dirname, "client"));
|
|
46275
|
-
if (yield* exists(join(bundledClient, "index.html")).pipe(orElseSucceed(() => false))) return bundledClient;
|
|
46276
|
-
const monorepoClient = resolve(join(import.meta.dirname, "../../web/dist"));
|
|
46277
|
-
if (yield* exists(join(monorepoClient, "index.html")).pipe(orElseSucceed(() => false))) return monorepoClient;
|
|
46278
|
-
});
|
|
46253
|
+
return 200;
|
|
46254
|
+
}
|
|
46279
46255
|
//#endregion
|
|
46280
|
-
//#region ../../packages/
|
|
46281
|
-
const
|
|
46282
|
-
|
|
46283
|
-
|
|
46256
|
+
//#region ../../packages/contracts/src/settings/commit-message-prompt.ts
|
|
46257
|
+
const DEFAULT_COMMIT_MESSAGE_PROMPT = `Generate a concise git commit message for the following changes. Follow conventional commit format (e.g., feat:, fix:, refactor:, docs:, etc.). Keep the summary line under 72 characters. Only output the commit message, nothing else.
|
|
46258
|
+
|
|
46259
|
+
Changes:
|
|
46260
|
+
{diff}`;
|
|
46261
|
+
function normalizeLineEndings$1(value) {
|
|
46262
|
+
return value.replace(/\r\n/g, "\n");
|
|
46284
46263
|
}
|
|
46285
|
-
function
|
|
46286
|
-
return
|
|
46264
|
+
function normalizeCommitMessagePrompt(value) {
|
|
46265
|
+
if (typeof value !== "string") return null;
|
|
46266
|
+
const normalized = normalizeLineEndings$1(value).trim();
|
|
46267
|
+
return normalized.length > 0 ? normalized : null;
|
|
46287
46268
|
}
|
|
46288
|
-
|
|
46289
|
-
|
|
46269
|
+
//#endregion
|
|
46270
|
+
//#region ../../packages/contracts/src/settings/auto-roll.ts
|
|
46271
|
+
const DEFAULT_AUTO_ROLL_ENABLED = false;
|
|
46272
|
+
const DEFAULT_AUTO_ROLL_REARM_REMAINING_THRESHOLD = 15;
|
|
46273
|
+
const DEFAULT_AUTO_ROLL_SWITCH_REMAINING_THRESHOLD = 5;
|
|
46274
|
+
const DEFAULT_RESTART_OFFICIAL_CODEX_ON_AUTO_ROLL = false;
|
|
46275
|
+
const DEFAULT_LAUNCH_OFFICIAL_CODEX_WHEN_CLOSED_ON_AUTO_ROLL = false;
|
|
46276
|
+
const DEFAULT_AUTO_ROLL_PRIORITY_ORDER = [];
|
|
46277
|
+
const DEFAULT_LOW_REMAINING_NOTIFICATION_ENABLED = false;
|
|
46278
|
+
const DEFAULT_LOW_REMAINING_NOTIFICATION_THRESHOLD = 1;
|
|
46279
|
+
const AUTO_ROLL_SWITCH_REMAINING_MIN = 0;
|
|
46280
|
+
const AUTO_ROLL_SWITCH_REMAINING_MAX = 50;
|
|
46281
|
+
const AUTO_ROLL_REARM_REMAINING_MAX = 100;
|
|
46282
|
+
const LOW_REMAINING_NOTIFICATION_MIN = 1;
|
|
46283
|
+
const LOW_REMAINING_NOTIFICATION_MAX = 50;
|
|
46284
|
+
function clampNumber(value, min, max) {
|
|
46285
|
+
return Math.min(max, Math.max(min, value));
|
|
46290
46286
|
}
|
|
46291
|
-
function
|
|
46292
|
-
return
|
|
46293
|
-
if (!SHELL_ENV_NAME_PATTERN.test(name)) throw new Error(`Unsupported environment variable name: ${name}`);
|
|
46294
|
-
return [
|
|
46295
|
-
`printf '%s\\n' '${envCaptureStart(name)}'`,
|
|
46296
|
-
`printenv ${name} || true`,
|
|
46297
|
-
`printf '%s\\n' '${envCaptureEnd(name)}'`
|
|
46298
|
-
].join("; ");
|
|
46299
|
-
}).join("; ");
|
|
46287
|
+
function resolveFiniteNumber(value, fallback) {
|
|
46288
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
46300
46289
|
}
|
|
46301
|
-
function
|
|
46302
|
-
|
|
46303
|
-
const endMarker = envCaptureEnd(name);
|
|
46304
|
-
const startIndex = output.indexOf(startMarker);
|
|
46305
|
-
if (startIndex === -1) return void 0;
|
|
46306
|
-
const valueStartIndex = startIndex + startMarker.length;
|
|
46307
|
-
const endIndex = output.indexOf(endMarker, valueStartIndex);
|
|
46308
|
-
if (endIndex === -1) return void 0;
|
|
46309
|
-
let value = output.slice(valueStartIndex, endIndex);
|
|
46310
|
-
if (value.startsWith("\n")) value = value.slice(1);
|
|
46311
|
-
if (value.endsWith("\n")) value = value.slice(0, -1);
|
|
46312
|
-
return value.length > 0 ? value : void 0;
|
|
46290
|
+
function legacyUsedThresholdToRemaining(value, fallbackUsed) {
|
|
46291
|
+
return 100 - clampNumber(resolveFiniteNumber(value, fallbackUsed), 0, 100);
|
|
46313
46292
|
}
|
|
46314
|
-
|
|
46315
|
-
|
|
46316
|
-
|
|
46317
|
-
|
|
46318
|
-
|
|
46319
|
-
|
|
46320
|
-
|
|
46321
|
-
|
|
46322
|
-
|
|
46323
|
-
|
|
46293
|
+
function sanitizeAutoRollSwitchRemainingThreshold(value) {
|
|
46294
|
+
return clampNumber(resolveFiniteNumber(value, 5), 0, 50);
|
|
46295
|
+
}
|
|
46296
|
+
function sanitizeAutoRollRearmRemainingThreshold(value, switchRemainingThreshold) {
|
|
46297
|
+
const sanitizedSwitch = sanitizeAutoRollSwitchRemainingThreshold(switchRemainingThreshold);
|
|
46298
|
+
return clampNumber(resolveFiniteNumber(value, 15), sanitizedSwitch + 1, 100);
|
|
46299
|
+
}
|
|
46300
|
+
function sanitizeAutoRollThresholds(rearmRemainingThreshold, switchRemainingThreshold) {
|
|
46301
|
+
const sanitizedSwitch = sanitizeAutoRollSwitchRemainingThreshold(switchRemainingThreshold);
|
|
46302
|
+
return {
|
|
46303
|
+
rearmRemainingThreshold: sanitizeAutoRollRearmRemainingThreshold(rearmRemainingThreshold, sanitizedSwitch),
|
|
46304
|
+
switchRemainingThreshold: sanitizedSwitch
|
|
46305
|
+
};
|
|
46306
|
+
}
|
|
46307
|
+
function sanitizeAutoRollPriorityOrder(value) {
|
|
46308
|
+
if (!Array.isArray(value)) return [...DEFAULT_AUTO_ROLL_PRIORITY_ORDER];
|
|
46309
|
+
const seen = /* @__PURE__ */ new Set();
|
|
46310
|
+
const normalized = [];
|
|
46311
|
+
for (const item of value) {
|
|
46312
|
+
if (typeof item !== "string") continue;
|
|
46313
|
+
const trimmed = item.trim();
|
|
46314
|
+
if (!trimmed || seen.has(trimmed)) continue;
|
|
46315
|
+
seen.add(trimmed);
|
|
46316
|
+
normalized.push(trimmed);
|
|
46324
46317
|
}
|
|
46325
|
-
return
|
|
46326
|
-
}
|
|
46318
|
+
return normalized;
|
|
46319
|
+
}
|
|
46320
|
+
function sanitizeLowRemainingNotificationThreshold(value) {
|
|
46321
|
+
return clampNumber(resolveFiniteNumber(value, 1), 1, 50);
|
|
46322
|
+
}
|
|
46323
|
+
function normalizeAutoRollSettings(raw) {
|
|
46324
|
+
const enabled = typeof raw?.enabled === "boolean" ? raw.enabled : false;
|
|
46325
|
+
const rawSwitchRemaining = typeof raw?.switchRemainingThreshold === "number" ? raw.switchRemainingThreshold : legacyUsedThresholdToRemaining(raw?.switchThreshold, 95);
|
|
46326
|
+
const { rearmRemainingThreshold: normalizedRearm, switchRemainingThreshold: normalizedSwitch } = sanitizeAutoRollThresholds(typeof raw?.rearmRemainingThreshold === "number" ? raw.rearmRemainingThreshold : legacyUsedThresholdToRemaining(raw?.warningThreshold, 85), rawSwitchRemaining);
|
|
46327
|
+
return {
|
|
46328
|
+
enabled,
|
|
46329
|
+
rearmRemainingThreshold: normalizedRearm,
|
|
46330
|
+
switchRemainingThreshold: normalizedSwitch,
|
|
46331
|
+
restartOfficialCodexOnAutoRoll: raw?.restartOfficialCodexOnAutoRoll === true ? true : false,
|
|
46332
|
+
launchOfficialCodexWhenClosedOnAutoRoll: raw?.launchOfficialCodexWhenClosedOnAutoRoll === true ? true : false,
|
|
46333
|
+
priorityOrder: sanitizeAutoRollPriorityOrder(raw?.priorityOrder),
|
|
46334
|
+
lowRemainingNotificationEnabled: raw?.lowRemainingNotificationEnabled === true ? true : false,
|
|
46335
|
+
lowRemainingNotificationThreshold: sanitizeLowRemainingNotificationThreshold(typeof raw?.lowRemainingNotificationThreshold === "number" ? raw.lowRemainingNotificationThreshold : NaN)
|
|
46336
|
+
};
|
|
46337
|
+
}
|
|
46327
46338
|
//#endregion
|
|
46328
|
-
//#region src/
|
|
46329
|
-
|
|
46330
|
-
|
|
46339
|
+
//#region ../../packages/runtime-app-state/src/storage/documents.ts
|
|
46340
|
+
const APP_STORAGE_TABLE = "app_storage_documents";
|
|
46341
|
+
const APP_STORAGE_DB_DIR = "t3-projects";
|
|
46342
|
+
const APP_STORAGE_DB_NAME = "state.sqlite";
|
|
46343
|
+
const SQLITE_BUSY_TIMEOUT_MS = 5e3;
|
|
46344
|
+
const SQLITE_BUSY_MAX_ATTEMPTS = 3;
|
|
46345
|
+
const SQLITE_BUSY_RETRY_DELAY_MS = 100;
|
|
46346
|
+
const writeQueueByDbPath = /* @__PURE__ */ new Map();
|
|
46347
|
+
const initializedDbPaths = /* @__PURE__ */ new Set();
|
|
46348
|
+
var AppStorageCorruptionError = class extends Error {
|
|
46349
|
+
constructor(message, options) {
|
|
46350
|
+
super(message);
|
|
46351
|
+
this.name = "AppStorageCorruptionError";
|
|
46352
|
+
this.dbPath = options.dbPath;
|
|
46353
|
+
this.namespace = options.namespace ?? null;
|
|
46354
|
+
if (options.cause !== void 0) this.cause = options.cause;
|
|
46355
|
+
}
|
|
46356
|
+
};
|
|
46357
|
+
function isRecord$9(value) {
|
|
46358
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
46359
|
+
}
|
|
46360
|
+
function clone$1(value) {
|
|
46361
|
+
return JSON.parse(JSON.stringify(value));
|
|
46362
|
+
}
|
|
46363
|
+
function safeParseJson(raw) {
|
|
46364
|
+
if (typeof raw !== "string" || raw.trim().length === 0) return null;
|
|
46331
46365
|
try {
|
|
46332
|
-
|
|
46333
|
-
|
|
46366
|
+
return JSON.parse(raw);
|
|
46367
|
+
} catch {
|
|
46368
|
+
return null;
|
|
46369
|
+
}
|
|
46370
|
+
}
|
|
46371
|
+
function parseJsonStrict(raw, options) {
|
|
46372
|
+
if (typeof raw !== "string" || raw.trim().length === 0) return null;
|
|
46373
|
+
try {
|
|
46374
|
+
return JSON.parse(raw);
|
|
46375
|
+
} catch (error) {
|
|
46376
|
+
throw new AppStorageCorruptionError(`App storage document ${options.namespace} contains invalid JSON.`, {
|
|
46377
|
+
dbPath: options.dbPath,
|
|
46378
|
+
namespace: options.namespace,
|
|
46379
|
+
cause: error
|
|
46380
|
+
});
|
|
46381
|
+
}
|
|
46382
|
+
}
|
|
46383
|
+
function sleep(ms) {
|
|
46384
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
46385
|
+
}
|
|
46386
|
+
function isSqliteBusyError(error) {
|
|
46387
|
+
if (!error || typeof error !== "object") return false;
|
|
46388
|
+
const sqliteError = error;
|
|
46389
|
+
if (sqliteError.cause && sqliteError.cause !== error && isSqliteBusyError(sqliteError.cause)) return true;
|
|
46390
|
+
if (sqliteError.error && sqliteError.error !== error && isSqliteBusyError(sqliteError.error)) return true;
|
|
46391
|
+
const message = typeof sqliteError.message === "string" ? sqliteError.message.toLowerCase() : String(error).toLowerCase();
|
|
46392
|
+
return sqliteError.code === "SQLITE_BUSY" || sqliteError.errno === 5 || message.includes("sqlite_busy") || message.includes("database is locked");
|
|
46393
|
+
}
|
|
46394
|
+
function isSqliteCorruptionError(error) {
|
|
46395
|
+
if (!error || typeof error !== "object") return false;
|
|
46396
|
+
const sqliteError = error;
|
|
46397
|
+
if (sqliteError.cause && sqliteError.cause !== error && isSqliteCorruptionError(sqliteError.cause)) return true;
|
|
46398
|
+
if (sqliteError.error && sqliteError.error !== error && isSqliteCorruptionError(sqliteError.error)) return true;
|
|
46399
|
+
const message = typeof sqliteError.message === "string" ? sqliteError.message.toLowerCase() : "";
|
|
46400
|
+
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");
|
|
46401
|
+
}
|
|
46402
|
+
function isAppStorageCorruptionError(error) {
|
|
46403
|
+
return error instanceof AppStorageCorruptionError || isSqliteCorruptionError(error);
|
|
46404
|
+
}
|
|
46405
|
+
function beginImmediate(db) {
|
|
46406
|
+
db.exec("BEGIN IMMEDIATE");
|
|
46407
|
+
}
|
|
46408
|
+
function commit(db) {
|
|
46409
|
+
db.exec("COMMIT");
|
|
46410
|
+
}
|
|
46411
|
+
function rollback(db) {
|
|
46412
|
+
try {
|
|
46413
|
+
db.exec("ROLLBACK");
|
|
46334
46414
|
} catch {}
|
|
46335
46415
|
}
|
|
46336
|
-
|
|
46337
|
-
const
|
|
46338
|
-
|
|
46339
|
-
|
|
46340
|
-
|
|
46341
|
-
|
|
46342
|
-
const resolveStateDir = fn(function* (raw) {
|
|
46343
|
-
const { join, resolve } = yield* Path$1;
|
|
46344
|
-
if (!raw || raw.trim().length === 0) return join(OS.homedir(), ".t3", "userdata");
|
|
46345
|
-
return resolve(yield* expandHomePath$1(raw.trim()));
|
|
46346
|
-
});
|
|
46347
|
-
//#endregion
|
|
46348
|
-
//#region ../../packages/t3-contracts/src/baseSchemas.ts
|
|
46349
|
-
const TrimmedString = Trim;
|
|
46350
|
-
const TrimmedNonEmptyString = TrimmedString.check(isNonEmpty());
|
|
46351
|
-
const NonNegativeInt = Int.check(isGreaterThanOrEqualTo(0));
|
|
46352
|
-
const PositiveInt = Int.check(isGreaterThanOrEqualTo(1));
|
|
46353
|
-
const IsoDateTime = String$1;
|
|
46354
|
-
/**
|
|
46355
|
-
* Construct a branded identifier. Enforces non-empty trimmed strings
|
|
46356
|
-
*/
|
|
46357
|
-
const makeEntityId = (brand$2) => TrimmedNonEmptyString.pipe(brand(brand$2));
|
|
46358
|
-
const ThreadId = makeEntityId("ThreadId");
|
|
46359
|
-
const ProjectId = makeEntityId("ProjectId");
|
|
46360
|
-
const CommandId = makeEntityId("CommandId");
|
|
46361
|
-
const EventId = makeEntityId("EventId");
|
|
46362
|
-
const MessageId = makeEntityId("MessageId");
|
|
46363
|
-
const TurnId = makeEntityId("TurnId");
|
|
46364
|
-
const ProviderItemId = makeEntityId("ProviderItemId");
|
|
46365
|
-
const RuntimeSessionId = makeEntityId("RuntimeSessionId");
|
|
46366
|
-
const RuntimeItemId = makeEntityId("RuntimeItemId");
|
|
46367
|
-
const RuntimeRequestId = makeEntityId("RuntimeRequestId");
|
|
46368
|
-
const RuntimeTaskId = makeEntityId("RuntimeTaskId");
|
|
46369
|
-
const ApprovalRequestId = makeEntityId("ApprovalRequestId");
|
|
46370
|
-
const CheckpointRef = makeEntityId("CheckpointRef");
|
|
46371
|
-
//#endregion
|
|
46372
|
-
//#region ../../packages/t3-contracts/src/terminal.ts
|
|
46373
|
-
const DEFAULT_TERMINAL_ID = "default";
|
|
46374
|
-
const TrimmedNonEmptyStringSchema$3 = TrimmedNonEmptyString;
|
|
46375
|
-
const TerminalColsSchema = Int.check(isGreaterThanOrEqualTo(1)).check(isLessThanOrEqualTo(1e3));
|
|
46376
|
-
const TerminalRowsSchema = Int.check(isGreaterThanOrEqualTo(1)).check(isLessThanOrEqualTo(500));
|
|
46377
|
-
const TerminalIdSchema = TrimmedNonEmptyStringSchema$3.check(isMaxLength(128));
|
|
46378
|
-
const TerminalEnvKeySchema = String$1.check(isPattern(/^[A-Za-z_][A-Za-z0-9_]*$/)).check(isMaxLength(128));
|
|
46379
|
-
const TerminalEnvValueSchema = String$1.check(isMaxLength(8192));
|
|
46380
|
-
const TerminalEnvSchema = Record(TerminalEnvKeySchema, TerminalEnvValueSchema).check(isMaxProperties(128));
|
|
46381
|
-
const TerminalIdWithDefaultSchema = TerminalIdSchema.pipe(withDecodingDefault(() => DEFAULT_TERMINAL_ID));
|
|
46382
|
-
const TerminalThreadInput = Struct({ threadId: TrimmedNonEmptyStringSchema$3 });
|
|
46383
|
-
const TerminalSessionInput = Struct({
|
|
46384
|
-
...TerminalThreadInput.fields,
|
|
46385
|
-
terminalId: TerminalIdWithDefaultSchema
|
|
46386
|
-
});
|
|
46387
|
-
const TerminalOpenInput = Struct({
|
|
46388
|
-
...TerminalSessionInput.fields,
|
|
46389
|
-
cwd: TrimmedNonEmptyStringSchema$3,
|
|
46390
|
-
cols: optional$2(TerminalColsSchema),
|
|
46391
|
-
rows: optional$2(TerminalRowsSchema),
|
|
46392
|
-
env: optional$2(TerminalEnvSchema)
|
|
46393
|
-
});
|
|
46394
|
-
const TerminalWriteInput = Struct({
|
|
46395
|
-
...TerminalSessionInput.fields,
|
|
46396
|
-
data: String$1.check(isNonEmpty()).check(isMaxLength(65536))
|
|
46397
|
-
});
|
|
46398
|
-
const TerminalResizeInput = Struct({
|
|
46399
|
-
...TerminalSessionInput.fields,
|
|
46400
|
-
cols: TerminalColsSchema,
|
|
46401
|
-
rows: TerminalRowsSchema
|
|
46402
|
-
});
|
|
46403
|
-
const TerminalClearInput = TerminalSessionInput;
|
|
46404
|
-
const TerminalRestartInput = Struct({
|
|
46405
|
-
...TerminalSessionInput.fields,
|
|
46406
|
-
cwd: TrimmedNonEmptyStringSchema$3,
|
|
46407
|
-
cols: TerminalColsSchema,
|
|
46408
|
-
rows: TerminalRowsSchema,
|
|
46409
|
-
env: optional$2(TerminalEnvSchema)
|
|
46410
|
-
});
|
|
46411
|
-
const TerminalCloseInput = Struct({
|
|
46412
|
-
...TerminalThreadInput.fields,
|
|
46413
|
-
terminalId: optional$2(TerminalIdSchema),
|
|
46414
|
-
deleteHistory: optional$2(Boolean$2)
|
|
46415
|
-
});
|
|
46416
|
-
const TerminalSessionStatus = Literals([
|
|
46417
|
-
"starting",
|
|
46418
|
-
"running",
|
|
46419
|
-
"exited",
|
|
46420
|
-
"error"
|
|
46421
|
-
]);
|
|
46422
|
-
const TerminalSessionSnapshot = Struct({
|
|
46423
|
-
threadId: String$1.check(isNonEmpty()),
|
|
46424
|
-
terminalId: String$1.check(isNonEmpty()),
|
|
46425
|
-
cwd: String$1.check(isNonEmpty()),
|
|
46426
|
-
status: TerminalSessionStatus,
|
|
46427
|
-
pid: NullOr(Int.check(isGreaterThan(0))),
|
|
46428
|
-
history: String$1,
|
|
46429
|
-
exitCode: NullOr(Int),
|
|
46430
|
-
exitSignal: NullOr(Int),
|
|
46431
|
-
updatedAt: String$1
|
|
46432
|
-
});
|
|
46433
|
-
const TerminalEventBaseSchema = Struct({
|
|
46434
|
-
threadId: String$1.check(isNonEmpty()),
|
|
46435
|
-
terminalId: String$1.check(isNonEmpty()),
|
|
46436
|
-
createdAt: String$1
|
|
46437
|
-
});
|
|
46438
|
-
const TerminalStartedEvent = Struct({
|
|
46439
|
-
...TerminalEventBaseSchema.fields,
|
|
46440
|
-
type: Literal("started"),
|
|
46441
|
-
snapshot: TerminalSessionSnapshot
|
|
46442
|
-
});
|
|
46443
|
-
const TerminalOutputEvent = Struct({
|
|
46444
|
-
...TerminalEventBaseSchema.fields,
|
|
46445
|
-
type: Literal("output"),
|
|
46446
|
-
data: String$1
|
|
46447
|
-
});
|
|
46448
|
-
const TerminalExitedEvent = Struct({
|
|
46449
|
-
...TerminalEventBaseSchema.fields,
|
|
46450
|
-
type: Literal("exited"),
|
|
46451
|
-
exitCode: NullOr(Int),
|
|
46452
|
-
exitSignal: NullOr(Int)
|
|
46453
|
-
});
|
|
46454
|
-
const TerminalErrorEvent = Struct({
|
|
46455
|
-
...TerminalEventBaseSchema.fields,
|
|
46456
|
-
type: Literal("error"),
|
|
46457
|
-
message: String$1.check(isNonEmpty())
|
|
46458
|
-
});
|
|
46459
|
-
const TerminalClearedEvent = Struct({
|
|
46460
|
-
...TerminalEventBaseSchema.fields,
|
|
46461
|
-
type: Literal("cleared")
|
|
46462
|
-
});
|
|
46463
|
-
const TerminalRestartedEvent = Struct({
|
|
46464
|
-
...TerminalEventBaseSchema.fields,
|
|
46465
|
-
type: Literal("restarted"),
|
|
46466
|
-
snapshot: TerminalSessionSnapshot
|
|
46467
|
-
});
|
|
46468
|
-
const TerminalActivityEvent = Struct({
|
|
46469
|
-
...TerminalEventBaseSchema.fields,
|
|
46470
|
-
type: Literal("activity"),
|
|
46471
|
-
hasRunningSubprocess: Boolean$2
|
|
46472
|
-
});
|
|
46473
|
-
const TerminalEvent = Union([
|
|
46474
|
-
TerminalStartedEvent,
|
|
46475
|
-
TerminalOutputEvent,
|
|
46476
|
-
TerminalExitedEvent,
|
|
46477
|
-
TerminalErrorEvent,
|
|
46478
|
-
TerminalClearedEvent,
|
|
46479
|
-
TerminalRestartedEvent,
|
|
46480
|
-
TerminalActivityEvent
|
|
46481
|
-
]);
|
|
46482
|
-
//#endregion
|
|
46483
|
-
//#region ../../packages/t3-contracts/src/model.ts
|
|
46484
|
-
const CODEX_REASONING_EFFORT_OPTIONS = [
|
|
46485
|
-
"xhigh",
|
|
46486
|
-
"high",
|
|
46487
|
-
"medium",
|
|
46488
|
-
"low"
|
|
46489
|
-
];
|
|
46490
|
-
const CodexModelOptions = Struct({
|
|
46491
|
-
reasoningEffort: optional$2(Literals(CODEX_REASONING_EFFORT_OPTIONS)),
|
|
46492
|
-
fastMode: optional$2(Boolean$2)
|
|
46493
|
-
});
|
|
46494
|
-
const ProviderModelOptions = Struct({ codex: optional$2(CodexModelOptions) });
|
|
46495
|
-
const MODEL_OPTIONS_BY_PROVIDER = { codex: [
|
|
46496
|
-
{
|
|
46497
|
-
slug: "gpt-5.5",
|
|
46498
|
-
name: "GPT-5.5"
|
|
46499
|
-
},
|
|
46500
|
-
{
|
|
46501
|
-
slug: "gpt-5.4",
|
|
46502
|
-
name: "GPT-5.4"
|
|
46503
|
-
},
|
|
46504
|
-
{
|
|
46505
|
-
slug: "gpt-5.4-mini",
|
|
46506
|
-
name: "GPT-5.4 Mini"
|
|
46507
|
-
},
|
|
46508
|
-
{
|
|
46509
|
-
slug: "gpt-5.3-codex",
|
|
46510
|
-
name: "GPT-5.3 Codex"
|
|
46511
|
-
},
|
|
46512
|
-
{
|
|
46513
|
-
slug: "gpt-5.3-codex-spark",
|
|
46514
|
-
name: "GPT-5.3 Codex Spark"
|
|
46416
|
+
function useStatement(db, sql, task) {
|
|
46417
|
+
const statement = db.prepare(sql);
|
|
46418
|
+
try {
|
|
46419
|
+
return task(statement);
|
|
46420
|
+
} finally {
|
|
46421
|
+
statement.finalize?.();
|
|
46515
46422
|
}
|
|
46516
|
-
] };
|
|
46517
|
-
const DEFAULT_MODEL_BY_PROVIDER = { codex: "gpt-5.5" };
|
|
46518
|
-
const DEFAULT_GIT_TEXT_GENERATION_MODEL = "gpt-5.4-mini";
|
|
46519
|
-
const MODEL_SLUG_ALIASES_BY_PROVIDER = { codex: {
|
|
46520
|
-
"gpt-5-codex": "gpt-5.5",
|
|
46521
|
-
"5.5": "gpt-5.5",
|
|
46522
|
-
"5.4": "gpt-5.4",
|
|
46523
|
-
"5.3": "gpt-5.3-codex",
|
|
46524
|
-
"gpt-5.3": "gpt-5.3-codex",
|
|
46525
|
-
"5.3-spark": "gpt-5.3-codex-spark",
|
|
46526
|
-
"gpt-5.3-spark": "gpt-5.3-codex-spark"
|
|
46527
|
-
} };
|
|
46528
|
-
//#endregion
|
|
46529
|
-
//#region ../../packages/t3-contracts/src/orchestration.ts
|
|
46530
|
-
const ORCHESTRATION_WS_METHODS = {
|
|
46531
|
-
getSnapshot: "orchestration.getSnapshot",
|
|
46532
|
-
getThreadSnapshot: "orchestration.getThreadSnapshot",
|
|
46533
|
-
subscribeShell: "orchestration.subscribeShell",
|
|
46534
|
-
subscribeThread: "orchestration.subscribeThread",
|
|
46535
|
-
syncExternalThreads: "orchestration.syncExternalThreads",
|
|
46536
|
-
dispatchCommand: "orchestration.dispatchCommand",
|
|
46537
|
-
getTurnDiff: "orchestration.getTurnDiff",
|
|
46538
|
-
getFullThreadDiff: "orchestration.getFullThreadDiff",
|
|
46539
|
-
replayEvents: "orchestration.replayEvents"
|
|
46540
|
-
};
|
|
46541
|
-
const ORCHESTRATION_WS_CHANNELS = { domainEvent: "orchestration.domainEvent" };
|
|
46542
|
-
const ProviderKind = Literal("codex");
|
|
46543
|
-
const ProviderApprovalPolicy = Literals([
|
|
46544
|
-
"untrusted",
|
|
46545
|
-
"on-failure",
|
|
46546
|
-
"on-request",
|
|
46547
|
-
"never"
|
|
46548
|
-
]);
|
|
46549
|
-
const ProviderSandboxMode = Literals([
|
|
46550
|
-
"read-only",
|
|
46551
|
-
"workspace-write",
|
|
46552
|
-
"danger-full-access"
|
|
46553
|
-
]);
|
|
46554
|
-
const CodexModelSelection = Struct({
|
|
46555
|
-
provider: Literal("codex"),
|
|
46556
|
-
model: TrimmedNonEmptyString,
|
|
46557
|
-
options: optional$2(CodexModelOptions)
|
|
46558
|
-
});
|
|
46559
|
-
const ModelSelection = CodexModelSelection;
|
|
46560
|
-
const CodexProviderStartOptions$1 = Struct({
|
|
46561
|
-
binaryPath: optional$2(TrimmedNonEmptyString),
|
|
46562
|
-
args: optional$2(String$1),
|
|
46563
|
-
homePath: optional$2(TrimmedNonEmptyString)
|
|
46564
|
-
});
|
|
46565
|
-
const ProviderStartOptions$1 = Struct({ codex: optional$2(CodexProviderStartOptions$1) });
|
|
46566
|
-
const RuntimeMode = Literals(["approval-required", "full-access"]);
|
|
46567
|
-
const DEFAULT_RUNTIME_MODE$2 = "full-access";
|
|
46568
|
-
const ProviderInteractionMode = Literals(["default", "plan"]);
|
|
46569
|
-
const DEFAULT_PROVIDER_INTERACTION_MODE = "default";
|
|
46570
|
-
const ThreadOrigin = Literals(["native", "external-import"]);
|
|
46571
|
-
const DEFAULT_THREAD_ORIGIN = "native";
|
|
46572
|
-
const ProviderRequestKind = Literals([
|
|
46573
|
-
"command",
|
|
46574
|
-
"file-read",
|
|
46575
|
-
"file-change"
|
|
46576
|
-
]);
|
|
46577
|
-
const AssistantDeliveryMode = Literals(["buffered", "streaming"]);
|
|
46578
|
-
const ProviderApprovalDecision = Literals([
|
|
46579
|
-
"accept",
|
|
46580
|
-
"acceptForSession",
|
|
46581
|
-
"decline",
|
|
46582
|
-
"cancel"
|
|
46583
|
-
]);
|
|
46584
|
-
const ProviderUserInputAnswers = Record(String$1, Unknown);
|
|
46585
|
-
function supportsCheckpointingForThreadOrigin(origin) {
|
|
46586
|
-
return origin === "native";
|
|
46587
46423
|
}
|
|
46588
|
-
|
|
46589
|
-
const
|
|
46590
|
-
|
|
46591
|
-
const
|
|
46592
|
-
|
|
46593
|
-
|
|
46594
|
-
|
|
46595
|
-
|
|
46596
|
-
|
|
46597
|
-
|
|
46598
|
-
|
|
46599
|
-
|
|
46600
|
-
|
|
46601
|
-
|
|
46602
|
-
|
|
46603
|
-
|
|
46604
|
-
|
|
46605
|
-
|
|
46606
|
-
|
|
46607
|
-
|
|
46608
|
-
|
|
46424
|
+
async function withWriteQueue(dbPath, task) {
|
|
46425
|
+
const previous = writeQueueByDbPath.get(dbPath) ?? Promise.resolve();
|
|
46426
|
+
let release;
|
|
46427
|
+
const current = new Promise((resolve) => {
|
|
46428
|
+
release = resolve;
|
|
46429
|
+
});
|
|
46430
|
+
writeQueueByDbPath.set(dbPath, current);
|
|
46431
|
+
await previous;
|
|
46432
|
+
try {
|
|
46433
|
+
return await task();
|
|
46434
|
+
} finally {
|
|
46435
|
+
release?.();
|
|
46436
|
+
if (writeQueueByDbPath.get(dbPath) === current) writeQueueByDbPath.delete(dbPath);
|
|
46437
|
+
}
|
|
46438
|
+
}
|
|
46439
|
+
function applyConnectionPragmas(db) {
|
|
46440
|
+
db.exec(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS};`);
|
|
46441
|
+
db.exec("PRAGMA journal_mode = WAL;");
|
|
46442
|
+
db.exec("PRAGMA foreign_keys = ON;");
|
|
46443
|
+
}
|
|
46444
|
+
function ensureSchema(db, dbPath) {
|
|
46445
|
+
if (initializedDbPaths.has(dbPath)) return;
|
|
46446
|
+
db.exec(`
|
|
46447
|
+
CREATE TABLE IF NOT EXISTS ${APP_STORAGE_TABLE} (
|
|
46448
|
+
namespace TEXT PRIMARY KEY,
|
|
46449
|
+
value_json TEXT NOT NULL,
|
|
46450
|
+
updated_at TEXT NOT NULL
|
|
46451
|
+
)
|
|
46452
|
+
`);
|
|
46453
|
+
initializedDbPaths.add(dbPath);
|
|
46454
|
+
}
|
|
46455
|
+
async function openDatabase(dbPath) {
|
|
46456
|
+
await promises.mkdir(nodePath.dirname(dbPath), { recursive: true });
|
|
46457
|
+
if (process.versions.bun !== void 0) {
|
|
46458
|
+
const database = new (await (Function("return import('bun:sqlite')")())).Database(dbPath);
|
|
46459
|
+
return {
|
|
46460
|
+
exec: database.exec.bind(database),
|
|
46461
|
+
prepare: database.prepare.bind(database),
|
|
46462
|
+
close: database.close.bind(database)
|
|
46463
|
+
};
|
|
46464
|
+
}
|
|
46465
|
+
const database = new (await (Function("return import('node:sqlite')")())).DatabaseSync(dbPath);
|
|
46466
|
+
return {
|
|
46467
|
+
exec: database.exec.bind(database),
|
|
46468
|
+
prepare: database.prepare.bind(database),
|
|
46469
|
+
close: database.close.bind(database)
|
|
46470
|
+
};
|
|
46471
|
+
}
|
|
46472
|
+
function resetAppStorageInitialization(dbPath) {
|
|
46473
|
+
initializedDbPaths.delete(dbPath);
|
|
46474
|
+
}
|
|
46475
|
+
async function backupCorruptAppStorageDb(dbPath) {
|
|
46476
|
+
const backupPath = `${dbPath}.corrupt-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
|
|
46477
|
+
let moved = false;
|
|
46478
|
+
for (const suffix of [
|
|
46479
|
+
"",
|
|
46480
|
+
"-wal",
|
|
46481
|
+
"-shm"
|
|
46482
|
+
]) {
|
|
46483
|
+
const source = `${dbPath}${suffix}`;
|
|
46484
|
+
const destination = `${backupPath}${suffix}`;
|
|
46485
|
+
try {
|
|
46486
|
+
if (!(await promises.stat(source)).isFile()) continue;
|
|
46487
|
+
await promises.rename(source, destination);
|
|
46488
|
+
moved = true;
|
|
46489
|
+
} catch (error) {
|
|
46490
|
+
if (error.code !== "ENOENT") throw error;
|
|
46491
|
+
}
|
|
46492
|
+
}
|
|
46493
|
+
resetAppStorageInitialization(dbPath);
|
|
46494
|
+
return moved ? backupPath : null;
|
|
46495
|
+
}
|
|
46496
|
+
async function withDatabase(dbPath, task) {
|
|
46497
|
+
for (let attempt = 1; attempt <= SQLITE_BUSY_MAX_ATTEMPTS; attempt += 1) {
|
|
46498
|
+
let db = null;
|
|
46499
|
+
try {
|
|
46500
|
+
db = await openDatabase(dbPath);
|
|
46501
|
+
applyConnectionPragmas(db);
|
|
46502
|
+
ensureSchema(db, dbPath);
|
|
46503
|
+
return task(db);
|
|
46504
|
+
} catch (error) {
|
|
46505
|
+
if (error instanceof AppStorageCorruptionError) throw error;
|
|
46506
|
+
if (isSqliteCorruptionError(error)) throw new AppStorageCorruptionError("App storage database is corrupt.", {
|
|
46507
|
+
dbPath,
|
|
46508
|
+
cause: error
|
|
46509
|
+
});
|
|
46510
|
+
if (!isSqliteBusyError(error) || attempt >= SQLITE_BUSY_MAX_ATTEMPTS) throw error;
|
|
46511
|
+
} finally {
|
|
46512
|
+
db?.close();
|
|
46513
|
+
}
|
|
46514
|
+
await sleep(SQLITE_BUSY_RETRY_DELAY_MS * attempt);
|
|
46515
|
+
}
|
|
46516
|
+
throw new Error("App storage database remained busy after retrying.");
|
|
46517
|
+
}
|
|
46518
|
+
function resolveAppStorageDbPath(userDataDir) {
|
|
46519
|
+
return nodePath.join(userDataDir, APP_STORAGE_DB_DIR, APP_STORAGE_DB_NAME);
|
|
46520
|
+
}
|
|
46521
|
+
async function readDocument(dbPath, namespace, normalize) {
|
|
46522
|
+
return withDatabase(dbPath, (db) => {
|
|
46523
|
+
const row = useStatement(db, `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`, (statement) => statement.get(namespace));
|
|
46524
|
+
const parsed = isRecord$9(row) ? safeParseJson(row.valueJson) : null;
|
|
46525
|
+
if (parsed === null) return null;
|
|
46526
|
+
return normalize(parsed);
|
|
46527
|
+
});
|
|
46528
|
+
}
|
|
46529
|
+
async function readDocumentStrict(dbPath, namespace, normalize) {
|
|
46530
|
+
return withDatabase(dbPath, (db) => {
|
|
46531
|
+
const row = useStatement(db, `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`, (statement) => statement.get(namespace));
|
|
46532
|
+
if (!isRecord$9(row)) return null;
|
|
46533
|
+
const parsed = parseJsonStrict(row.valueJson, {
|
|
46534
|
+
dbPath,
|
|
46535
|
+
namespace
|
|
46536
|
+
});
|
|
46537
|
+
if (parsed === null) throw new AppStorageCorruptionError(`App storage document ${namespace} is empty.`, {
|
|
46538
|
+
dbPath,
|
|
46539
|
+
namespace
|
|
46540
|
+
});
|
|
46541
|
+
try {
|
|
46542
|
+
return normalize(parsed);
|
|
46543
|
+
} catch (error) {
|
|
46544
|
+
throw new AppStorageCorruptionError(`App storage document ${namespace} failed normalization.`, {
|
|
46545
|
+
dbPath,
|
|
46546
|
+
namespace,
|
|
46547
|
+
cause: error
|
|
46548
|
+
});
|
|
46549
|
+
}
|
|
46550
|
+
});
|
|
46551
|
+
}
|
|
46552
|
+
async function writeDocument(dbPath, namespace, value) {
|
|
46553
|
+
return withWriteQueue(dbPath, async () => withDatabase(dbPath, (db) => {
|
|
46554
|
+
const normalizedValue = clone$1(value);
|
|
46555
|
+
beginImmediate(db);
|
|
46556
|
+
try {
|
|
46557
|
+
useStatement(db, `
|
|
46558
|
+
INSERT INTO ${APP_STORAGE_TABLE} (namespace, value_json, updated_at)
|
|
46559
|
+
VALUES (?, ?, ?)
|
|
46560
|
+
ON CONFLICT(namespace)
|
|
46561
|
+
DO UPDATE SET
|
|
46562
|
+
value_json = excluded.value_json,
|
|
46563
|
+
updated_at = excluded.updated_at
|
|
46564
|
+
`, (statement) => statement.run(namespace, JSON.stringify(normalizedValue), (/* @__PURE__ */ new Date()).toISOString()));
|
|
46565
|
+
commit(db);
|
|
46566
|
+
return normalizedValue;
|
|
46567
|
+
} catch (error) {
|
|
46568
|
+
rollback(db);
|
|
46569
|
+
throw error;
|
|
46570
|
+
}
|
|
46571
|
+
}));
|
|
46572
|
+
}
|
|
46573
|
+
async function updateDocument(input) {
|
|
46574
|
+
return withWriteQueue(input.dbPath, async () => withDatabase(input.dbPath, (db) => {
|
|
46575
|
+
beginImmediate(db);
|
|
46576
|
+
try {
|
|
46577
|
+
const row = useStatement(db, `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`, (statement) => statement.get(input.namespace));
|
|
46578
|
+
const current = isRecord$9(row) ? input.normalize(safeParseJson(row.valueJson) ?? input.fallback()) : input.fallback();
|
|
46579
|
+
const next = input.normalize(input.transform(clone$1(current)));
|
|
46580
|
+
useStatement(db, `
|
|
46581
|
+
INSERT INTO ${APP_STORAGE_TABLE} (namespace, value_json, updated_at)
|
|
46582
|
+
VALUES (?, ?, ?)
|
|
46583
|
+
ON CONFLICT(namespace)
|
|
46584
|
+
DO UPDATE SET
|
|
46585
|
+
value_json = excluded.value_json,
|
|
46586
|
+
updated_at = excluded.updated_at
|
|
46587
|
+
`, (statement) => statement.run(input.namespace, JSON.stringify(next), (/* @__PURE__ */ new Date()).toISOString()));
|
|
46588
|
+
commit(db);
|
|
46589
|
+
return clone$1(next);
|
|
46590
|
+
} catch (error) {
|
|
46591
|
+
rollback(db);
|
|
46592
|
+
throw error;
|
|
46593
|
+
}
|
|
46594
|
+
}));
|
|
46595
|
+
}
|
|
46596
|
+
//#endregion
|
|
46597
|
+
//#region ../../packages/runtime-app-state/src/app/state.ts
|
|
46598
|
+
const LEGACY_APP_STATE_FILE = "app-state.json";
|
|
46599
|
+
const APP_STATE_DOCUMENT = "desktop.app-state";
|
|
46600
|
+
const APP_NAME = "codexuse-desktop";
|
|
46601
|
+
let configuredUserDataDir = null;
|
|
46602
|
+
let appStateCache = null;
|
|
46603
|
+
let writeLock = Promise.resolve();
|
|
46604
|
+
const writeLockContext = new AsyncLocalStorage();
|
|
46605
|
+
function isRecord$8(value) {
|
|
46606
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
46607
|
+
}
|
|
46608
|
+
function clone(value) {
|
|
46609
|
+
return JSON.parse(JSON.stringify(value));
|
|
46610
|
+
}
|
|
46611
|
+
function resolveDefaultUserDataDir() {
|
|
46612
|
+
const home = process.env.HOME || process.env.USERPROFILE || nodeOs.homedir();
|
|
46613
|
+
if (!home) throw new Error("Unable to resolve home directory for app state.");
|
|
46614
|
+
if (process.platform === "darwin") return nodePath.join(home, "Library", "Application Support", APP_NAME);
|
|
46615
|
+
if (process.platform === "win32") {
|
|
46616
|
+
const appData = process.env.APPDATA;
|
|
46617
|
+
if (appData) return nodePath.join(appData, APP_NAME);
|
|
46618
|
+
return nodePath.join(home, "AppData", "Roaming", APP_NAME);
|
|
46619
|
+
}
|
|
46620
|
+
return nodePath.join(home, ".config", APP_NAME);
|
|
46621
|
+
}
|
|
46622
|
+
function getUserDataDir() {
|
|
46623
|
+
return configuredUserDataDir ?? resolveDefaultUserDataDir();
|
|
46624
|
+
}
|
|
46625
|
+
function resolveLegacyAppStatePath() {
|
|
46626
|
+
return nodePath.join(getUserDataDir(), LEGACY_APP_STATE_FILE);
|
|
46627
|
+
}
|
|
46628
|
+
function resolveStorageDbPath() {
|
|
46629
|
+
return resolveAppStorageDbPath(getUserDataDir());
|
|
46630
|
+
}
|
|
46631
|
+
function createDefaultAppState() {
|
|
46632
|
+
return {
|
|
46633
|
+
schemaVersion: 1,
|
|
46634
|
+
autoRoll: {
|
|
46635
|
+
enabled: false,
|
|
46636
|
+
rearmRemainingThreshold: 15,
|
|
46637
|
+
switchRemainingThreshold: 5,
|
|
46638
|
+
restartOfficialCodexOnAutoRoll: false,
|
|
46639
|
+
launchOfficialCodexWhenClosedOnAutoRoll: false,
|
|
46640
|
+
priorityOrder: [],
|
|
46641
|
+
lowRemainingNotificationEnabled: false,
|
|
46642
|
+
lowRemainingNotificationThreshold: 1
|
|
46643
|
+
},
|
|
46644
|
+
officialCodex: {
|
|
46645
|
+
lastProfileSwitchAt: null,
|
|
46646
|
+
lastProfileSwitchProfileKey: null,
|
|
46647
|
+
lastVerifiedLaunchAt: null,
|
|
46648
|
+
lastVerifiedLaunchProfileKey: null,
|
|
46649
|
+
lastObservedPid: null,
|
|
46650
|
+
lastRestartStatus: null,
|
|
46651
|
+
lastRestartReason: null,
|
|
46652
|
+
activity: [],
|
|
46653
|
+
instancesByProfileName: {},
|
|
46654
|
+
pendingRestartDebt: null
|
|
46655
|
+
},
|
|
46656
|
+
app: {
|
|
46657
|
+
lastAppVersion: null,
|
|
46658
|
+
pendingUpdateVersion: null,
|
|
46659
|
+
lastProfileName: null
|
|
46660
|
+
},
|
|
46661
|
+
license: {
|
|
46662
|
+
licenseKey: null,
|
|
46663
|
+
purchaseEmail: null,
|
|
46664
|
+
lastVerifiedAt: null,
|
|
46665
|
+
nextCheckAt: null,
|
|
46666
|
+
lastVerificationError: null,
|
|
46667
|
+
status: "inactive",
|
|
46668
|
+
signature: null
|
|
46669
|
+
},
|
|
46670
|
+
preferences: {
|
|
46671
|
+
excludeFolders: [],
|
|
46672
|
+
enableTaskCompleteBeep: true,
|
|
46673
|
+
preventSleepDuringTasks: true,
|
|
46674
|
+
chatHistoryScrollbackItems: 200,
|
|
46675
|
+
systemNotificationsEnabled: true,
|
|
46676
|
+
subagentSystemNotificationsEnabled: true,
|
|
46677
|
+
folderHistory: [],
|
|
46678
|
+
pinnedPaths: []
|
|
46679
|
+
},
|
|
46680
|
+
runtimeSettings: {},
|
|
46681
|
+
ui: {
|
|
46682
|
+
themeMode: null,
|
|
46683
|
+
layout: { sidebarCollapsed: null },
|
|
46684
|
+
profiles: {
|
|
46685
|
+
viewMode: null,
|
|
46686
|
+
sortBy: null,
|
|
46687
|
+
groupBy: null,
|
|
46688
|
+
planFilter: null,
|
|
46689
|
+
healthFilter: null,
|
|
46690
|
+
customGroupFilter: null,
|
|
46691
|
+
toolbarOpen: null,
|
|
46692
|
+
collapsedSections: {}
|
|
46693
|
+
},
|
|
46694
|
+
onboarding: {
|
|
46695
|
+
welcomeCompleted: false,
|
|
46696
|
+
welcomeCompletedAt: null,
|
|
46697
|
+
welcomeResumeStep: null,
|
|
46698
|
+
milestones: {
|
|
46699
|
+
firstProfileAdded: false,
|
|
46700
|
+
secondProfileAdded: false
|
|
46701
|
+
},
|
|
46702
|
+
sessionCount: 0,
|
|
46703
|
+
nudgeCooldowns: {},
|
|
46704
|
+
nudgeDismissCount: {},
|
|
46705
|
+
proUnlockedCelebrated: false
|
|
46706
|
+
},
|
|
46707
|
+
projectThreadSelections: {},
|
|
46708
|
+
duplicateWarningDismissedKey: null,
|
|
46709
|
+
pendingLicenseActivation: false
|
|
46710
|
+
},
|
|
46711
|
+
profileDashboard: { customGroupsByAccountKey: {} },
|
|
46712
|
+
workspaceSettingsByPath: {},
|
|
46713
|
+
conversationCategoriesByCwd: {},
|
|
46714
|
+
conversationCategoryAssignmentsByCwd: {},
|
|
46715
|
+
git: { commitMessagePrompt: DEFAULT_COMMIT_MESSAGE_PROMPT },
|
|
46716
|
+
skills: {
|
|
46717
|
+
sources: [],
|
|
46718
|
+
installsBySlug: {}
|
|
46719
|
+
},
|
|
46720
|
+
sync: {
|
|
46721
|
+
lastPushAt: null,
|
|
46722
|
+
lastPullAt: null,
|
|
46723
|
+
lastError: null,
|
|
46724
|
+
remoteUpdatedAt: null
|
|
46725
|
+
},
|
|
46726
|
+
analytics: {
|
|
46727
|
+
anonymousId: null,
|
|
46728
|
+
enabled: true,
|
|
46729
|
+
lastFlushAt: null,
|
|
46730
|
+
lastError: null
|
|
46731
|
+
},
|
|
46732
|
+
profilesByName: {},
|
|
46733
|
+
migration: {
|
|
46734
|
+
status: "pending",
|
|
46735
|
+
startedAt: null,
|
|
46736
|
+
completedAt: null,
|
|
46737
|
+
localStorageImportedAt: null,
|
|
46738
|
+
lastError: null
|
|
46739
|
+
}
|
|
46740
|
+
};
|
|
46741
|
+
}
|
|
46742
|
+
function asString$11(value) {
|
|
46743
|
+
if (typeof value !== "string") return null;
|
|
46744
|
+
const trimmed = value.trim();
|
|
46745
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
46746
|
+
}
|
|
46747
|
+
function asNumberOrNull(value) {
|
|
46748
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
46749
|
+
}
|
|
46750
|
+
function asBooleanOrNull(value) {
|
|
46751
|
+
return typeof value === "boolean" ? value : null;
|
|
46752
|
+
}
|
|
46753
|
+
function normalizeAppState(raw) {
|
|
46754
|
+
const defaults = createDefaultAppState();
|
|
46755
|
+
if (!isRecord$8(raw)) return defaults;
|
|
46756
|
+
const rawAutoRoll = isRecord$8(raw.autoRoll) ? raw.autoRoll : void 0;
|
|
46757
|
+
const merged = clone(deepMerge(defaults, raw));
|
|
46758
|
+
merged.schemaVersion = 1;
|
|
46759
|
+
merged.autoRoll = normalizeAutoRollSettings(rawAutoRoll);
|
|
46760
|
+
if (!isRecord$8(merged.officialCodex)) merged.officialCodex = clone(defaults.officialCodex);
|
|
46761
|
+
merged.officialCodex.lastProfileSwitchAt = asNumberOrNull(merged.officialCodex.lastProfileSwitchAt);
|
|
46762
|
+
merged.officialCodex.lastProfileSwitchProfileKey = asString$11(merged.officialCodex.lastProfileSwitchProfileKey);
|
|
46763
|
+
merged.officialCodex.lastVerifiedLaunchAt = asNumberOrNull(merged.officialCodex.lastVerifiedLaunchAt);
|
|
46764
|
+
merged.officialCodex.lastVerifiedLaunchProfileKey = asString$11(merged.officialCodex.lastVerifiedLaunchProfileKey);
|
|
46765
|
+
merged.officialCodex.lastObservedPid = asNumberOrNull(merged.officialCodex.lastObservedPid);
|
|
46766
|
+
merged.officialCodex.lastRestartStatus = asString$11(merged.officialCodex.lastRestartStatus);
|
|
46767
|
+
merged.officialCodex.lastRestartReason = asString$11(merged.officialCodex.lastRestartReason);
|
|
46768
|
+
merged.officialCodex.activity = Array.isArray(merged.officialCodex.activity) ? merged.officialCodex.activity.filter((entry) => isRecord$8(entry)).map((entry) => ({
|
|
46769
|
+
id: asString$11(entry.id) ?? "",
|
|
46770
|
+
at: asString$11(entry.at) ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
46771
|
+
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",
|
|
46772
|
+
status: asString$11(entry.status) ?? "unknown",
|
|
46773
|
+
reason: asString$11(entry.reason),
|
|
46774
|
+
decisionId: asString$11(entry.decisionId),
|
|
46775
|
+
profileName: asString$11(entry.profileName),
|
|
46776
|
+
sourceProfileName: asString$11(entry.sourceProfileName),
|
|
46777
|
+
targetProfileName: asString$11(entry.targetProfileName),
|
|
46778
|
+
remainingPercent: asNumberOrNull(entry.remainingPercent),
|
|
46779
|
+
threshold: asNumberOrNull(entry.threshold),
|
|
46780
|
+
snapshotAgeMs: asNumberOrNull(entry.snapshotAgeMs),
|
|
46781
|
+
snapshotSource: asString$11(entry.snapshotSource),
|
|
46782
|
+
phase: asString$11(entry.phase),
|
|
46783
|
+
pid: asNumberOrNull(entry.pid),
|
|
46784
|
+
profileKeyHash: asString$11(entry.profileKeyHash),
|
|
46785
|
+
switchVerified: asBooleanOrNull(entry.switchVerified),
|
|
46786
|
+
restartRequested: asBooleanOrNull(entry.restartRequested),
|
|
46787
|
+
restartResult: asString$11(entry.restartResult),
|
|
46788
|
+
observedProfileName: asString$11(entry.observedProfileName),
|
|
46789
|
+
observedProfileKeyHash: asString$11(entry.observedProfileKeyHash),
|
|
46790
|
+
observedProfileMatchSource: asString$11(entry.observedProfileMatchSource)
|
|
46791
|
+
})).filter((entry) => entry.id && entry.at).slice(-50) : [];
|
|
46792
|
+
if (!isRecord$8(merged.officialCodex.instancesByProfileName)) merged.officialCodex.instancesByProfileName = {};
|
|
46793
|
+
else {
|
|
46794
|
+
const nextInstances = {};
|
|
46795
|
+
for (const [key, value] of Object.entries(merged.officialCodex.instancesByProfileName)) {
|
|
46796
|
+
if (!isRecord$8(value)) continue;
|
|
46797
|
+
const profileName = asString$11(value.profileName) ?? asString$11(key);
|
|
46798
|
+
if (!profileName) continue;
|
|
46799
|
+
nextInstances[profileName] = {
|
|
46800
|
+
profileName,
|
|
46801
|
+
profileKey: asString$11(value.profileKey),
|
|
46802
|
+
profileHome: asString$11(value.profileHome),
|
|
46803
|
+
appPath: asString$11(value.appPath),
|
|
46804
|
+
bundleId: asString$11(value.bundleId),
|
|
46805
|
+
pid: asNumberOrNull(value.pid),
|
|
46806
|
+
appServerPid: asNumberOrNull(value.appServerPid),
|
|
46807
|
+
launchedAt: asNumberOrNull(value.launchedAt),
|
|
46808
|
+
lastVerifiedAt: asNumberOrNull(value.lastVerifiedAt),
|
|
46809
|
+
lastStatus: asString$11(value.lastStatus),
|
|
46810
|
+
lastError: asString$11(value.lastError)
|
|
46811
|
+
};
|
|
46812
|
+
}
|
|
46813
|
+
merged.officialCodex.instancesByProfileName = nextInstances;
|
|
46814
|
+
}
|
|
46815
|
+
if (isRecord$8(merged.officialCodex.pendingRestartDebt)) {
|
|
46816
|
+
const debt = merged.officialCodex.pendingRestartDebt;
|
|
46817
|
+
const targetProfileName = asString$11(debt.targetProfileName);
|
|
46818
|
+
merged.officialCodex.pendingRestartDebt = targetProfileName ? {
|
|
46819
|
+
targetProfileName,
|
|
46820
|
+
targetProfileKey: asString$11(debt.targetProfileKey),
|
|
46821
|
+
sourceProfileName: asString$11(debt.sourceProfileName),
|
|
46822
|
+
sourceProfileKey: asString$11(debt.sourceProfileKey),
|
|
46823
|
+
decisionId: asString$11(debt.decisionId),
|
|
46824
|
+
attempts: asNumberOrNull(debt.attempts) ?? 0,
|
|
46825
|
+
lastReason: asString$11(debt.lastReason)
|
|
46826
|
+
} : null;
|
|
46827
|
+
} else merged.officialCodex.pendingRestartDebt = null;
|
|
46828
|
+
merged.app.lastAppVersion = asString$11(merged.app.lastAppVersion);
|
|
46829
|
+
merged.app.pendingUpdateVersion = asString$11(merged.app.pendingUpdateVersion);
|
|
46830
|
+
merged.app.lastProfileName = asString$11(merged.app.lastProfileName);
|
|
46831
|
+
{
|
|
46832
|
+
const allowedAppKeys = new Set(Object.keys(defaults.app));
|
|
46833
|
+
for (const key of Object.keys(merged.app)) if (!allowedAppKeys.has(key)) delete merged.app[key];
|
|
46834
|
+
}
|
|
46835
|
+
merged.license.licenseKey = asString$11(merged.license.licenseKey);
|
|
46836
|
+
merged.license.purchaseEmail = asString$11(merged.license.purchaseEmail);
|
|
46837
|
+
merged.license.lastVerifiedAt = asString$11(merged.license.lastVerifiedAt);
|
|
46838
|
+
merged.license.nextCheckAt = asString$11(merged.license.nextCheckAt);
|
|
46839
|
+
merged.license.lastVerificationError = asString$11(merged.license.lastVerificationError);
|
|
46840
|
+
merged.license.signature = asString$11(merged.license.signature);
|
|
46841
|
+
if (![
|
|
46842
|
+
"inactive",
|
|
46843
|
+
"active",
|
|
46844
|
+
"grace",
|
|
46845
|
+
"error"
|
|
46846
|
+
].includes(merged.license.status)) merged.license.status = "inactive";
|
|
46847
|
+
if (!Array.isArray(merged.preferences.excludeFolders)) merged.preferences.excludeFolders = [];
|
|
46848
|
+
if (typeof merged.preferences.enableTaskCompleteBeep !== "boolean") merged.preferences.enableTaskCompleteBeep = true;
|
|
46849
|
+
if (typeof merged.preferences.preventSleepDuringTasks !== "boolean") merged.preferences.preventSleepDuringTasks = true;
|
|
46850
|
+
merged.preferences.chatHistoryScrollbackItems = normalizeChatHistoryScrollbackItems(merged.preferences.chatHistoryScrollbackItems);
|
|
46851
|
+
if (typeof merged.preferences.systemNotificationsEnabled !== "boolean") merged.preferences.systemNotificationsEnabled = true;
|
|
46852
|
+
if (typeof merged.preferences.subagentSystemNotificationsEnabled !== "boolean") merged.preferences.subagentSystemNotificationsEnabled = true;
|
|
46853
|
+
if (!Array.isArray(merged.preferences.folderHistory)) merged.preferences.folderHistory = [];
|
|
46854
|
+
if (!Array.isArray(merged.preferences.pinnedPaths)) merged.preferences.pinnedPaths = [];
|
|
46855
|
+
{
|
|
46856
|
+
const allowedPreferenceKeys = new Set(Object.keys(defaults.preferences));
|
|
46857
|
+
for (const key of Object.keys(merged.preferences)) if (!allowedPreferenceKeys.has(key)) delete merged.preferences[key];
|
|
46858
|
+
}
|
|
46859
|
+
if (!isRecord$8(merged.runtimeSettings)) merged.runtimeSettings = {};
|
|
46860
|
+
if (!isRecord$8(merged.ui)) merged.ui = clone(defaults.ui);
|
|
46861
|
+
merged.ui.themeMode = merged.ui.themeMode === "light" || merged.ui.themeMode === "dark" ? merged.ui.themeMode : null;
|
|
46862
|
+
if (!isRecord$8(merged.ui.layout)) merged.ui.layout = clone(defaults.ui.layout);
|
|
46863
|
+
if (typeof merged.ui.layout.sidebarCollapsed !== "boolean") merged.ui.layout.sidebarCollapsed = null;
|
|
46864
|
+
if (!isRecord$8(merged.ui.profiles)) merged.ui.profiles = clone(defaults.ui.profiles);
|
|
46865
|
+
merged.ui.profiles.viewMode = merged.ui.profiles.viewMode === "cards" || merged.ui.profiles.viewMode === "compact" ? merged.ui.profiles.viewMode : null;
|
|
46866
|
+
merged.ui.profiles.sortBy = asString$11(merged.ui.profiles.sortBy);
|
|
46867
|
+
merged.ui.profiles.groupBy = asString$11(merged.ui.profiles.groupBy);
|
|
46868
|
+
merged.ui.profiles.planFilter = asString$11(merged.ui.profiles.planFilter);
|
|
46869
|
+
merged.ui.profiles.healthFilter = asString$11(merged.ui.profiles.healthFilter);
|
|
46870
|
+
merged.ui.profiles.customGroupFilter = asString$11(merged.ui.profiles.customGroupFilter);
|
|
46871
|
+
if (typeof merged.ui.profiles.toolbarOpen !== "boolean") merged.ui.profiles.toolbarOpen = null;
|
|
46872
|
+
if (!isRecord$8(merged.ui.profiles.collapsedSections)) merged.ui.profiles.collapsedSections = {};
|
|
46873
|
+
else merged.ui.profiles.collapsedSections = Object.fromEntries(Object.entries(merged.ui.profiles.collapsedSections).flatMap(([key, value]) => {
|
|
46874
|
+
const normalizedKey = asString$11(key);
|
|
46875
|
+
if (!normalizedKey || typeof value !== "boolean") return [];
|
|
46876
|
+
return [[normalizedKey, value]];
|
|
46877
|
+
}));
|
|
46878
|
+
if (!isRecord$8(merged.ui.onboarding)) merged.ui.onboarding = clone(defaults.ui.onboarding);
|
|
46879
|
+
if (typeof merged.ui.onboarding.welcomeCompleted !== "boolean") merged.ui.onboarding.welcomeCompleted = false;
|
|
46880
|
+
if (!Number.isFinite(merged.ui.onboarding.welcomeCompletedAt)) merged.ui.onboarding.welcomeCompletedAt = null;
|
|
46881
|
+
merged.ui.onboarding.welcomeResumeStep = merged.ui.onboarding.welcomeResumeStep === 2 ? 2 : null;
|
|
46882
|
+
if (!isRecord$8(merged.ui.onboarding.milestones)) merged.ui.onboarding.milestones = clone(defaults.ui.onboarding.milestones);
|
|
46883
|
+
if (typeof merged.ui.onboarding.milestones.firstProfileAdded !== "boolean") merged.ui.onboarding.milestones.firstProfileAdded = false;
|
|
46884
|
+
if (typeof merged.ui.onboarding.milestones.secondProfileAdded !== "boolean") merged.ui.onboarding.milestones.secondProfileAdded = false;
|
|
46885
|
+
if (!Number.isFinite(merged.ui.onboarding.sessionCount)) merged.ui.onboarding.sessionCount = 0;
|
|
46886
|
+
if (!isRecord$8(merged.ui.onboarding.nudgeCooldowns)) merged.ui.onboarding.nudgeCooldowns = {};
|
|
46887
|
+
else merged.ui.onboarding.nudgeCooldowns = Object.fromEntries(Object.entries(merged.ui.onboarding.nudgeCooldowns).flatMap(([key, value]) => {
|
|
46888
|
+
const normalizedKey = asString$11(key);
|
|
46889
|
+
if (!normalizedKey || !Number.isFinite(value)) return [];
|
|
46890
|
+
return [[normalizedKey, Number(value)]];
|
|
46891
|
+
}));
|
|
46892
|
+
if (!isRecord$8(merged.ui.onboarding.nudgeDismissCount)) merged.ui.onboarding.nudgeDismissCount = {};
|
|
46893
|
+
else merged.ui.onboarding.nudgeDismissCount = Object.fromEntries(Object.entries(merged.ui.onboarding.nudgeDismissCount).flatMap(([key, value]) => {
|
|
46894
|
+
const normalizedKey = asString$11(key);
|
|
46895
|
+
if (!normalizedKey || !Number.isFinite(value)) return [];
|
|
46896
|
+
return [[normalizedKey, Number(value)]];
|
|
46897
|
+
}));
|
|
46898
|
+
if (typeof merged.ui.onboarding.proUnlockedCelebrated !== "boolean") merged.ui.onboarding.proUnlockedCelebrated = false;
|
|
46899
|
+
if (!isRecord$8(merged.ui.projectThreadSelections)) merged.ui.projectThreadSelections = {};
|
|
46900
|
+
else merged.ui.projectThreadSelections = Object.fromEntries(Object.entries(merged.ui.projectThreadSelections).flatMap(([projectId, threadId]) => {
|
|
46901
|
+
const normalizedProjectId = asString$11(projectId);
|
|
46902
|
+
if (!normalizedProjectId) return [];
|
|
46903
|
+
return [[normalizedProjectId, typeof threadId === "string" && threadId.trim().length > 0 ? threadId.trim() : null]];
|
|
46904
|
+
}));
|
|
46905
|
+
merged.ui.duplicateWarningDismissedKey = asString$11(merged.ui.duplicateWarningDismissedKey);
|
|
46906
|
+
if (typeof merged.ui.pendingLicenseActivation !== "boolean") merged.ui.pendingLicenseActivation = false;
|
|
46907
|
+
{
|
|
46908
|
+
const allowedUiKeys = new Set(Object.keys(defaults.ui));
|
|
46909
|
+
for (const key of Object.keys(merged.ui)) if (!allowedUiKeys.has(key)) delete merged.ui[key];
|
|
46910
|
+
}
|
|
46911
|
+
if (!isRecord$8(merged.profileDashboard)) merged.profileDashboard = clone(defaults.profileDashboard);
|
|
46912
|
+
if (!isRecord$8(merged.profileDashboard.customGroupsByAccountKey)) merged.profileDashboard.customGroupsByAccountKey = {};
|
|
46913
|
+
else merged.profileDashboard.customGroupsByAccountKey = Object.fromEntries(Object.entries(merged.profileDashboard.customGroupsByAccountKey).flatMap(([key, value]) => {
|
|
46914
|
+
const normalizedKey = asString$11(key);
|
|
46915
|
+
const normalizedValue = asString$11(value);
|
|
46916
|
+
if (!normalizedKey || !normalizedValue) return [];
|
|
46917
|
+
return [[normalizedKey, normalizedValue]];
|
|
46918
|
+
}));
|
|
46919
|
+
{
|
|
46920
|
+
const allowedProfileDashboardKeys = new Set(Object.keys(defaults.profileDashboard));
|
|
46921
|
+
for (const key of Object.keys(merged.profileDashboard)) if (!allowedProfileDashboardKeys.has(key)) delete merged.profileDashboard[key];
|
|
46922
|
+
}
|
|
46923
|
+
const legacyProjectSettingsByPath = isRecord$8(raw.projectSettingsByPath) ? raw.projectSettingsByPath : null;
|
|
46924
|
+
if (!isRecord$8(merged.workspaceSettingsByPath)) merged.workspaceSettingsByPath = {};
|
|
46925
|
+
if (legacyProjectSettingsByPath) merged.workspaceSettingsByPath = {
|
|
46926
|
+
...legacyProjectSettingsByPath,
|
|
46927
|
+
...merged.workspaceSettingsByPath
|
|
46928
|
+
};
|
|
46929
|
+
delete merged.projectSettingsByPath;
|
|
46930
|
+
if (!isRecord$8(merged.conversationCategoriesByCwd)) merged.conversationCategoriesByCwd = {};
|
|
46931
|
+
if (!isRecord$8(merged.conversationCategoryAssignmentsByCwd)) merged.conversationCategoryAssignmentsByCwd = {};
|
|
46932
|
+
if (!isRecord$8(merged.git)) merged.git = clone(defaults.git);
|
|
46933
|
+
merged.git.commitMessagePrompt = normalizeCommitMessagePrompt(merged.git.commitMessagePrompt) ?? DEFAULT_COMMIT_MESSAGE_PROMPT;
|
|
46934
|
+
{
|
|
46935
|
+
const allowedGitKeys = new Set(Object.keys(defaults.git));
|
|
46936
|
+
for (const key of Object.keys(merged.git)) if (!allowedGitKeys.has(key)) delete merged.git[key];
|
|
46937
|
+
}
|
|
46938
|
+
if (!isRecord$8(merged.skills)) merged.skills = clone(defaults.skills);
|
|
46939
|
+
if (!Array.isArray(merged.skills.sources)) merged.skills.sources = [];
|
|
46940
|
+
if (!isRecord$8(merged.skills.installsBySlug)) merged.skills.installsBySlug = {};
|
|
46941
|
+
if (!isRecord$8(merged.sync)) merged.sync = clone(defaults.sync);
|
|
46942
|
+
merged.sync.lastPushAt = asString$11(merged.sync.lastPushAt);
|
|
46943
|
+
merged.sync.lastPullAt = asString$11(merged.sync.lastPullAt);
|
|
46944
|
+
merged.sync.lastError = asString$11(merged.sync.lastError);
|
|
46945
|
+
merged.sync.remoteUpdatedAt = asString$11(merged.sync.remoteUpdatedAt);
|
|
46946
|
+
if (!isRecord$8(merged.analytics)) merged.analytics = isRecord$8(merged.telemetry) ? clone(merged.telemetry) : clone(defaults.analytics);
|
|
46947
|
+
merged.analytics.anonymousId = asString$11(merged.analytics.anonymousId);
|
|
46948
|
+
if (!merged.analytics.anonymousId) {
|
|
46949
|
+
const legacyInstallId = asString$11(merged.telemetry?.installId);
|
|
46950
|
+
merged.analytics.anonymousId = legacyInstallId;
|
|
46951
|
+
}
|
|
46952
|
+
if (typeof merged.analytics.enabled !== "boolean") merged.analytics.enabled = true;
|
|
46953
|
+
merged.analytics.lastFlushAt = asString$11(merged.analytics.lastFlushAt);
|
|
46954
|
+
merged.analytics.lastError = asString$11(merged.analytics.lastError);
|
|
46955
|
+
if ("telemetry" in merged) delete merged.telemetry;
|
|
46956
|
+
if (!isRecord$8(merged.profilesByName)) merged.profilesByName = {};
|
|
46957
|
+
if (!isRecord$8(merged.migration)) merged.migration = clone(defaults.migration);
|
|
46958
|
+
if (![
|
|
46959
|
+
"pending",
|
|
46960
|
+
"pending_local_storage",
|
|
46961
|
+
"complete"
|
|
46962
|
+
].includes(merged.migration.status)) merged.migration.status = "pending";
|
|
46963
|
+
merged.migration.startedAt = asString$11(merged.migration.startedAt);
|
|
46964
|
+
merged.migration.completedAt = asString$11(merged.migration.completedAt);
|
|
46965
|
+
merged.migration.localStorageImportedAt = asString$11(merged.migration.localStorageImportedAt);
|
|
46966
|
+
merged.migration.lastError = asString$11(merged.migration.lastError);
|
|
46967
|
+
return merged;
|
|
46968
|
+
}
|
|
46969
|
+
function deepMerge(base, patch) {
|
|
46970
|
+
if (!isRecord$8(base) || !isRecord$8(patch)) return clone(patch ?? base);
|
|
46971
|
+
const next = { ...base };
|
|
46972
|
+
for (const [key, patchValue] of Object.entries(patch)) {
|
|
46973
|
+
if (patchValue === void 0) continue;
|
|
46974
|
+
const currentValue = next[key];
|
|
46975
|
+
if (Array.isArray(patchValue)) {
|
|
46976
|
+
next[key] = clone(patchValue);
|
|
46977
|
+
continue;
|
|
46978
|
+
}
|
|
46979
|
+
if (isRecord$8(currentValue) && isRecord$8(patchValue)) {
|
|
46980
|
+
next[key] = deepMerge(currentValue, patchValue);
|
|
46981
|
+
continue;
|
|
46982
|
+
}
|
|
46983
|
+
next[key] = clone(patchValue);
|
|
46984
|
+
}
|
|
46985
|
+
return next;
|
|
46986
|
+
}
|
|
46987
|
+
async function readLegacyAppStateFromDisk() {
|
|
46988
|
+
const filePath = resolveLegacyAppStatePath();
|
|
46989
|
+
try {
|
|
46990
|
+
const raw = await promises.readFile(filePath, "utf8");
|
|
46991
|
+
return normalizeAppState(JSON.parse(raw));
|
|
46992
|
+
} catch (error) {
|
|
46993
|
+
if (error.code === "ENOENT") return null;
|
|
46994
|
+
throw error;
|
|
46995
|
+
}
|
|
46996
|
+
}
|
|
46997
|
+
async function readAppStateFromStorage() {
|
|
46998
|
+
return readDocumentStrict(resolveStorageDbPath(), APP_STATE_DOCUMENT, normalizeAppState);
|
|
46999
|
+
}
|
|
47000
|
+
async function writeAppStateToStorage(state) {
|
|
47001
|
+
return writeDocument(resolveStorageDbPath(), APP_STATE_DOCUMENT, normalizeAppState(state));
|
|
47002
|
+
}
|
|
47003
|
+
function compactRecoveryMessage(error) {
|
|
47004
|
+
return (error instanceof Error ? error.message : typeof error === "string" ? error : String(error)).replace(/\s+/g, " ").trim().slice(0, 240) || "unknown corruption";
|
|
47005
|
+
}
|
|
47006
|
+
async function recoverCorruptAppStateStorage(error) {
|
|
47007
|
+
const dbPath = resolveStorageDbPath();
|
|
47008
|
+
if (error instanceof AppStorageCorruptionError && error.namespace === APP_STATE_DOCUMENT) {
|
|
47009
|
+
appStateCache = null;
|
|
47010
|
+
resetAppStorageInitialization(dbPath);
|
|
47011
|
+
const recovered = normalizeAppState(await readLegacyAppStateFromDisk().catch(() => null) ?? null);
|
|
47012
|
+
recovered.migration.lastError = `Recovered app-state document after corruption (${compactRecoveryMessage(error)}). Shared storage database preserved.`;
|
|
47013
|
+
return writeAppStateToStorage(recovered);
|
|
47014
|
+
}
|
|
47015
|
+
const backupPath = await backupCorruptAppStorageDb(dbPath);
|
|
47016
|
+
appStateCache = null;
|
|
47017
|
+
resetAppStorageInitialization(dbPath);
|
|
47018
|
+
const recovered = normalizeAppState(await readLegacyAppStateFromDisk().catch(() => null) ?? null);
|
|
47019
|
+
recovered.migration.lastError = backupPath ? `Recovered app-state storage after corruption (${compactRecoveryMessage(error)}). Backup: ${nodePath.basename(backupPath)}` : `Recovered app-state storage after corruption (${compactRecoveryMessage(error)}). No existing DB file was present.`;
|
|
47020
|
+
return writeAppStateToStorage(recovered);
|
|
47021
|
+
}
|
|
47022
|
+
async function ensureInitialized() {
|
|
47023
|
+
if (appStateCache) return appStateCache;
|
|
47024
|
+
let loaded = null;
|
|
47025
|
+
try {
|
|
47026
|
+
loaded = await readAppStateFromStorage() ?? await readLegacyAppStateFromDisk();
|
|
47027
|
+
} catch (error) {
|
|
47028
|
+
if (!isAppStorageCorruptionError(error)) throw error;
|
|
47029
|
+
appStateCache = await recoverCorruptAppStateStorage(error);
|
|
47030
|
+
return clone(appStateCache);
|
|
47031
|
+
}
|
|
47032
|
+
appStateCache = await writeAppStateToStorage(loaded ?? normalizeAppState(null));
|
|
47033
|
+
return clone(appStateCache);
|
|
47034
|
+
}
|
|
47035
|
+
async function withWriteLock(task) {
|
|
47036
|
+
if (writeLockContext.getStore()) return task();
|
|
47037
|
+
const previous = writeLock;
|
|
47038
|
+
let release;
|
|
47039
|
+
writeLock = new Promise((resolve) => {
|
|
47040
|
+
release = resolve;
|
|
47041
|
+
});
|
|
47042
|
+
await previous;
|
|
47043
|
+
try {
|
|
47044
|
+
return await writeLockContext.run(true, task);
|
|
47045
|
+
} finally {
|
|
47046
|
+
if (release) release();
|
|
47047
|
+
}
|
|
47048
|
+
}
|
|
47049
|
+
async function initializeAppState(userDataDir) {
|
|
47050
|
+
if (configuredUserDataDir !== userDataDir) {
|
|
47051
|
+
configuredUserDataDir = userDataDir;
|
|
47052
|
+
appStateCache = null;
|
|
47053
|
+
resetAppStorageInitialization(resolveStorageDbPath());
|
|
47054
|
+
}
|
|
47055
|
+
return clone(await ensureInitialized());
|
|
47056
|
+
}
|
|
47057
|
+
async function getAppState() {
|
|
47058
|
+
return clone(await ensureInitialized());
|
|
47059
|
+
}
|
|
47060
|
+
async function updateAppState(transform, options = {}) {
|
|
47061
|
+
const mode = options.mode ?? "patch";
|
|
47062
|
+
const allowBeforeMigrationComplete = options.allowBeforeMigrationComplete === true;
|
|
47063
|
+
return withWriteLock(async () => {
|
|
47064
|
+
const nextState = await updateDocument({
|
|
47065
|
+
dbPath: resolveStorageDbPath(),
|
|
47066
|
+
namespace: APP_STATE_DOCUMENT,
|
|
47067
|
+
normalize: normalizeAppState,
|
|
47068
|
+
fallback: createDefaultAppState,
|
|
47069
|
+
transform: (current) => {
|
|
47070
|
+
if (!allowBeforeMigrationComplete && current.migration.status !== "complete") throw new Error("Storage migration is not complete yet.");
|
|
47071
|
+
const transformed = transform(clone(current));
|
|
47072
|
+
return mode === "replace" ? normalizeAppState(transformed) : normalizeAppState(deepMerge(current, transformed));
|
|
47073
|
+
}
|
|
47074
|
+
});
|
|
47075
|
+
appStateCache = nextState;
|
|
47076
|
+
return clone(nextState);
|
|
47077
|
+
});
|
|
47078
|
+
}
|
|
47079
|
+
async function patchAppState(patch) {
|
|
47080
|
+
return updateAppState(() => patch, {
|
|
47081
|
+
mode: "patch",
|
|
47082
|
+
allowBeforeMigrationComplete: false
|
|
47083
|
+
});
|
|
47084
|
+
}
|
|
47085
|
+
//#endregion
|
|
47086
|
+
//#region ../../packages/contracts/src/settings/legacy-localstorage-keys.ts
|
|
47087
|
+
const LEGACY_LOCALSTORAGE_KEYS = [
|
|
47088
|
+
"settings-storage",
|
|
47089
|
+
"provider",
|
|
47090
|
+
"sandbox-storage",
|
|
47091
|
+
"project-settings-storage",
|
|
47092
|
+
"folder-storage",
|
|
47093
|
+
"conversation-categories-storage",
|
|
47094
|
+
"codex:auto-roll-settings"
|
|
47095
|
+
];
|
|
47096
|
+
//#endregion
|
|
47097
|
+
//#region ../../packages/shared/src/core/logger.ts
|
|
47098
|
+
const isTestEnv = process.env.NODE_ENV === "test" || process.env.VITEST === "true" || process.env.VITEST === "1";
|
|
47099
|
+
function isMocked(fn) {
|
|
47100
|
+
return Boolean(fn && typeof fn === "function" && "mock" in fn);
|
|
47101
|
+
}
|
|
47102
|
+
function logWarn(...args) {
|
|
47103
|
+
if (isTestEnv && !isMocked(console.warn)) return;
|
|
47104
|
+
console.warn(...args);
|
|
47105
|
+
}
|
|
47106
|
+
function logError(...args) {
|
|
47107
|
+
if (isTestEnv && !isMocked(console.error)) return;
|
|
47108
|
+
console.error(...args);
|
|
47109
|
+
}
|
|
47110
|
+
function logInfo(...args) {
|
|
47111
|
+
if (isTestEnv && !isMocked(console.info)) return;
|
|
47112
|
+
console.info(...args);
|
|
47113
|
+
}
|
|
47114
|
+
//#endregion
|
|
47115
|
+
//#region ../../packages/runtime-app-state/src/storage/migrations/v1.ts
|
|
47116
|
+
const SQLITE_STORAGE_DIR = ".f86eb5e712267207";
|
|
47117
|
+
const LEGACY_SETTINGS_FILE = "settings.json";
|
|
47118
|
+
const LEGACY_SETTINGS_BACKUP_FILE = "settings.json.bak";
|
|
47119
|
+
const LEGACY_SYNC_STATE_FILE = "sync-state.json";
|
|
47120
|
+
const LEGACY_APP_SETTINGS_PARITY_FILE = "app-settings-parity.json";
|
|
47121
|
+
const LEGACY_PROFILE_HOMES_DIR = "profile-homes";
|
|
47122
|
+
const LEGACY_SKILLS_DIR = "skills";
|
|
47123
|
+
const LEGACY_SKILL_CACHE_DIR = "skill-cache";
|
|
47124
|
+
const LEGACY_SKILLS_REPOS_FILE = "repos.json";
|
|
47125
|
+
const LEGACY_SKILL_MANIFEST = ".codexuse-skill.json";
|
|
47126
|
+
const LEGACY_LICENSE_SECRET_FILE$1 = "license.secret";
|
|
47127
|
+
function isRecord$7(value) {
|
|
47128
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
47129
|
+
}
|
|
47130
|
+
function asString$10(value) {
|
|
47131
|
+
if (typeof value !== "string") return null;
|
|
47132
|
+
const trimmed = value.trim();
|
|
47133
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
47134
|
+
}
|
|
47135
|
+
function isMissingPathError(error) {
|
|
47136
|
+
return error.code === "ENOENT";
|
|
47137
|
+
}
|
|
47138
|
+
function resolveHomeDir$1() {
|
|
47139
|
+
const home = process.env.HOME || process.env.USERPROFILE || nodeOs.homedir();
|
|
47140
|
+
if (!home) throw new Error("HOME is not set.");
|
|
47141
|
+
return home;
|
|
47142
|
+
}
|
|
47143
|
+
function resolveCodexDir() {
|
|
47144
|
+
return nodePath.join(resolveHomeDir$1(), ".codex");
|
|
47145
|
+
}
|
|
47146
|
+
function resolveLegacyPath(...segments) {
|
|
47147
|
+
return nodePath.join(resolveCodexDir(), ...segments);
|
|
47148
|
+
}
|
|
47149
|
+
async function readJsonFile(filePath) {
|
|
47150
|
+
const raw = await promises.readFile(filePath, "utf8");
|
|
47151
|
+
return JSON.parse(raw);
|
|
47152
|
+
}
|
|
47153
|
+
async function readJsonFileIfExists(filePath) {
|
|
47154
|
+
try {
|
|
47155
|
+
return await readJsonFile(filePath);
|
|
47156
|
+
} catch (error) {
|
|
47157
|
+
if (error.code === "ENOENT") return null;
|
|
47158
|
+
throw error;
|
|
47159
|
+
}
|
|
47160
|
+
}
|
|
47161
|
+
async function copyDirectoryManual(source, destination) {
|
|
47162
|
+
await promises.mkdir(destination, { recursive: true });
|
|
47163
|
+
const entries = await promises.readdir(source, { withFileTypes: true });
|
|
47164
|
+
for (const entry of entries) {
|
|
47165
|
+
const srcPath = nodePath.join(source, entry.name);
|
|
47166
|
+
const destPath = nodePath.join(destination, entry.name);
|
|
47167
|
+
if (entry.isSymbolicLink()) {
|
|
47168
|
+
const linkTarget = await promises.readlink(srcPath);
|
|
47169
|
+
await promises.symlink(linkTarget, destPath).catch((error) => {
|
|
47170
|
+
if (error.code !== "EEXIST") throw error;
|
|
47171
|
+
});
|
|
47172
|
+
continue;
|
|
47173
|
+
}
|
|
47174
|
+
if (entry.isDirectory()) {
|
|
47175
|
+
await copyDirectoryManual(srcPath, destPath);
|
|
47176
|
+
continue;
|
|
47177
|
+
}
|
|
47178
|
+
if (entry.isFile()) await promises.copyFile(srcPath, destPath);
|
|
47179
|
+
}
|
|
47180
|
+
}
|
|
47181
|
+
async function copyDirIfExists(source, destination) {
|
|
47182
|
+
let stats = null;
|
|
47183
|
+
try {
|
|
47184
|
+
stats = await promises.stat(source);
|
|
47185
|
+
} catch (error) {
|
|
47186
|
+
if (error.code === "ENOENT") return;
|
|
47187
|
+
throw error;
|
|
47188
|
+
}
|
|
47189
|
+
if (!stats.isDirectory()) return;
|
|
47190
|
+
await promises.rm(destination, {
|
|
47191
|
+
recursive: true,
|
|
47192
|
+
force: true
|
|
47193
|
+
});
|
|
47194
|
+
await promises.mkdir(nodePath.dirname(destination), { recursive: true });
|
|
47195
|
+
try {
|
|
47196
|
+
await promises.cp(source, destination, {
|
|
47197
|
+
recursive: true,
|
|
47198
|
+
errorOnExist: false,
|
|
47199
|
+
force: true,
|
|
47200
|
+
dereference: false,
|
|
47201
|
+
verbatimSymlinks: true
|
|
47202
|
+
});
|
|
47203
|
+
} catch (error) {
|
|
47204
|
+
if (error.code === "ERR_FS_CP_EINVAL") {
|
|
47205
|
+
await copyDirectoryManual(source, destination);
|
|
47206
|
+
return;
|
|
47207
|
+
}
|
|
47208
|
+
throw error;
|
|
47209
|
+
}
|
|
47210
|
+
}
|
|
47211
|
+
async function copyFileIfExists(source, destination, options) {
|
|
47212
|
+
try {
|
|
47213
|
+
if (!(await promises.stat(source)).isFile()) return;
|
|
47214
|
+
} catch (error) {
|
|
47215
|
+
if (error.code === "ENOENT") return;
|
|
47216
|
+
throw error;
|
|
47217
|
+
}
|
|
47218
|
+
try {
|
|
47219
|
+
if ((await promises.stat(destination)).isFile()) return;
|
|
47220
|
+
} catch (error) {
|
|
47221
|
+
if (error.code !== "ENOENT") throw error;
|
|
47222
|
+
}
|
|
47223
|
+
await promises.mkdir(nodePath.dirname(destination), { recursive: true });
|
|
47224
|
+
await promises.copyFile(source, destination);
|
|
47225
|
+
if (typeof options?.mode === "number") await promises.chmod(destination, options.mode).catch(() => void 0);
|
|
47226
|
+
}
|
|
47227
|
+
async function cleanupCopiedSkillsMetadata(skillsDir) {
|
|
47228
|
+
await removeIfExists(nodePath.join(skillsDir, LEGACY_SKILLS_REPOS_FILE));
|
|
47229
|
+
let entries = [];
|
|
47230
|
+
try {
|
|
47231
|
+
entries = await promises.readdir(skillsDir, { withFileTypes: true });
|
|
47232
|
+
} catch {
|
|
47233
|
+
return;
|
|
47234
|
+
}
|
|
47235
|
+
for (const entry of entries) {
|
|
47236
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
47237
|
+
await removeIfExists(nodePath.join(skillsDir, entry.name, LEGACY_SKILL_MANIFEST));
|
|
47238
|
+
}
|
|
47239
|
+
}
|
|
47240
|
+
async function migrateLegacyDirectoriesToUserData() {
|
|
47241
|
+
const userDataDir = getUserDataDir();
|
|
47242
|
+
const legacyCodexDir = resolveCodexDir();
|
|
47243
|
+
await copyDirIfExists(nodePath.join(legacyCodexDir, LEGACY_PROFILE_HOMES_DIR), nodePath.join(userDataDir, LEGACY_PROFILE_HOMES_DIR));
|
|
47244
|
+
await copyDirIfExists(nodePath.join(legacyCodexDir, LEGACY_SKILLS_DIR), nodePath.join(userDataDir, LEGACY_SKILLS_DIR));
|
|
47245
|
+
await copyDirIfExists(nodePath.join(legacyCodexDir, LEGACY_SKILL_CACHE_DIR), nodePath.join(userDataDir, LEGACY_SKILL_CACHE_DIR));
|
|
47246
|
+
await copyFileIfExists(nodePath.join(legacyCodexDir, LEGACY_LICENSE_SECRET_FILE$1), nodePath.join(userDataDir, LEGACY_LICENSE_SECRET_FILE$1), { mode: 384 });
|
|
47247
|
+
await cleanupCopiedSkillsMetadata(nodePath.join(userDataDir, LEGACY_SKILLS_DIR));
|
|
47248
|
+
}
|
|
47249
|
+
function pickAutoRoll(raw) {
|
|
47250
|
+
if (!raw) return null;
|
|
47251
|
+
try {
|
|
47252
|
+
return normalizeAutoRollSettings(raw);
|
|
47253
|
+
} catch {
|
|
47254
|
+
return null;
|
|
47255
|
+
}
|
|
47256
|
+
}
|
|
47257
|
+
function parseLegacyLicense(raw) {
|
|
47258
|
+
if (!isRecord$7(raw)) return {
|
|
47259
|
+
licenseKey: null,
|
|
47260
|
+
purchaseEmail: null,
|
|
47261
|
+
lastVerifiedAt: null,
|
|
47262
|
+
nextCheckAt: null,
|
|
47263
|
+
lastVerificationError: null,
|
|
47264
|
+
status: "inactive",
|
|
47265
|
+
signature: null
|
|
47266
|
+
};
|
|
47267
|
+
const statusCandidate = asString$10(raw.status);
|
|
47268
|
+
const status = [
|
|
47269
|
+
"inactive",
|
|
47270
|
+
"active",
|
|
47271
|
+
"grace",
|
|
47272
|
+
"error"
|
|
47273
|
+
].includes(statusCandidate ?? "") ? statusCandidate : "inactive";
|
|
47274
|
+
return {
|
|
47275
|
+
licenseKey: asString$10(raw.licenseKey ?? raw.license_key),
|
|
47276
|
+
purchaseEmail: asString$10(raw.purchaseEmail ?? raw.purchase_email),
|
|
47277
|
+
lastVerifiedAt: asString$10(raw.lastVerifiedAt ?? raw.last_verified_at),
|
|
47278
|
+
nextCheckAt: asString$10(raw.nextCheckAt ?? raw.next_check_at),
|
|
47279
|
+
lastVerificationError: asString$10(raw.lastVerificationError ?? raw.last_verification_error),
|
|
47280
|
+
status,
|
|
47281
|
+
signature: asString$10(raw.signature)
|
|
47282
|
+
};
|
|
47283
|
+
}
|
|
47284
|
+
function parseLegacyProfileRecord(name, raw) {
|
|
47285
|
+
if (!isRecord$7(raw)) return null;
|
|
47286
|
+
const dataRaw = raw.data;
|
|
47287
|
+
let data = null;
|
|
47288
|
+
if (isRecord$7(dataRaw)) data = dataRaw;
|
|
47289
|
+
else if (typeof dataRaw === "string") try {
|
|
47290
|
+
data = JSON.parse(dataRaw);
|
|
47291
|
+
} catch {
|
|
47292
|
+
data = null;
|
|
47293
|
+
}
|
|
47294
|
+
if (!data) return null;
|
|
47295
|
+
return {
|
|
47296
|
+
name,
|
|
47297
|
+
displayName: asString$10(raw.displayName ?? raw.display_name) ?? name,
|
|
47298
|
+
data,
|
|
47299
|
+
metadata: isRecord$7(raw.metadata) ? raw.metadata : void 0,
|
|
47300
|
+
accountId: asString$10(raw.accountId ?? raw.account_id),
|
|
47301
|
+
workspaceId: asString$10(raw.workspaceId ?? raw.workspace_id),
|
|
47302
|
+
workspaceName: asString$10(raw.workspaceName ?? raw.workspace_name),
|
|
47303
|
+
email: asString$10(raw.email),
|
|
47304
|
+
authMethod: asString$10(raw.authMethod ?? raw.auth_method),
|
|
47305
|
+
createdAt: asString$10(raw.createdAt ?? raw.created_at),
|
|
47306
|
+
updatedAt: asString$10(raw.updatedAt ?? raw.updated_at)
|
|
47307
|
+
};
|
|
47308
|
+
}
|
|
47309
|
+
async function loadLegacySettingsPatch() {
|
|
47310
|
+
const raw = await readJsonFileIfExists(resolveLegacyPath(LEGACY_SETTINGS_FILE));
|
|
47311
|
+
if (!isRecord$7(raw)) return {};
|
|
47312
|
+
const autoRoll = pickAutoRoll(raw.autoRoll ?? raw.auto_roll);
|
|
47313
|
+
const license = parseLegacyLicense(raw.license ?? raw.license_data ?? raw.license_state);
|
|
47314
|
+
return {
|
|
47315
|
+
app: {
|
|
47316
|
+
lastAppVersion: asString$10(raw.lastAppVersion ?? raw.last_app_version),
|
|
47317
|
+
pendingUpdateVersion: asString$10(raw.pendingUpdateVersion ?? raw.pending_update_version),
|
|
47318
|
+
lastProfileName: asString$10(raw.lastProfileName ?? raw.last_profile_name)
|
|
47319
|
+
},
|
|
47320
|
+
license,
|
|
47321
|
+
autoRoll: autoRoll ? {
|
|
47322
|
+
enabled: autoRoll.enabled,
|
|
47323
|
+
rearmRemainingThreshold: autoRoll.rearmRemainingThreshold,
|
|
47324
|
+
switchRemainingThreshold: autoRoll.switchRemainingThreshold,
|
|
47325
|
+
restartOfficialCodexOnAutoRoll: autoRoll.restartOfficialCodexOnAutoRoll,
|
|
47326
|
+
launchOfficialCodexWhenClosedOnAutoRoll: autoRoll.launchOfficialCodexWhenClosedOnAutoRoll,
|
|
47327
|
+
priorityOrder: autoRoll.priorityOrder,
|
|
47328
|
+
lowRemainingNotificationEnabled: autoRoll.lowRemainingNotificationEnabled,
|
|
47329
|
+
lowRemainingNotificationThreshold: autoRoll.lowRemainingNotificationThreshold
|
|
47330
|
+
} : void 0
|
|
47331
|
+
};
|
|
47332
|
+
}
|
|
47333
|
+
async function loadLegacySyncPatch() {
|
|
47334
|
+
const raw = await readJsonFileIfExists(resolveLegacyPath(LEGACY_SYNC_STATE_FILE));
|
|
47335
|
+
if (!isRecord$7(raw)) return {};
|
|
47336
|
+
return { sync: {
|
|
47337
|
+
lastPushAt: asString$10(raw.lastPushAt),
|
|
47338
|
+
lastPullAt: asString$10(raw.lastPullAt),
|
|
47339
|
+
lastError: asString$10(raw.lastError),
|
|
47340
|
+
remoteUpdatedAt: asString$10(raw.remoteUpdatedAt)
|
|
47341
|
+
} };
|
|
47342
|
+
}
|
|
47343
|
+
async function loadLegacyAppSettingsParityPatch() {
|
|
47344
|
+
const raw = await readJsonFileIfExists(nodePath.join(getUserDataDir(), LEGACY_APP_SETTINGS_PARITY_FILE));
|
|
47345
|
+
if (!isRecord$7(raw)) return {};
|
|
47346
|
+
return { runtimeSettings: raw };
|
|
47347
|
+
}
|
|
47348
|
+
async function loadLegacyProfilesPatch() {
|
|
47349
|
+
const root = resolveLegacyPath(LEGACY_PROFILE_HOMES_DIR);
|
|
47350
|
+
let entries = [];
|
|
47351
|
+
try {
|
|
47352
|
+
entries = await promises.readdir(root, { withFileTypes: true });
|
|
47353
|
+
} catch (error) {
|
|
47354
|
+
if (error.code === "ENOENT") return {};
|
|
47355
|
+
throw error;
|
|
47356
|
+
}
|
|
47357
|
+
const profilesByName = {};
|
|
47358
|
+
for (const entry of entries) {
|
|
47359
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
47360
|
+
const raw = await readJsonFileIfExists(nodePath.join(root, entry.name, "profile.json"));
|
|
47361
|
+
if (!raw) continue;
|
|
47362
|
+
const parsed = parseLegacyProfileRecord(entry.name, raw);
|
|
47363
|
+
if (!parsed) continue;
|
|
47364
|
+
profilesByName[entry.name] = parsed;
|
|
47365
|
+
}
|
|
47366
|
+
if (Object.keys(profilesByName).length === 0) return {};
|
|
47367
|
+
return { profilesByName };
|
|
47368
|
+
}
|
|
47369
|
+
function parseSkillInstallMetadata(raw) {
|
|
47370
|
+
if (!isRecord$7(raw)) return null;
|
|
47371
|
+
const id = asString$10(raw.id);
|
|
47372
|
+
if (!id) return null;
|
|
47373
|
+
return {
|
|
47374
|
+
id,
|
|
47375
|
+
repo: asString$10(raw.repo),
|
|
47376
|
+
repoPath: asString$10(raw.repoPath),
|
|
47377
|
+
sourceLabel: asString$10(raw.sourceLabel),
|
|
47378
|
+
sourceType: raw.sourceType === "official" || raw.sourceType === "community" || raw.sourceType === "local" ? raw.sourceType : void 0,
|
|
47379
|
+
viewUrl: asString$10(raw.viewUrl),
|
|
47380
|
+
createdAt: asString$10(raw.createdAt)
|
|
47381
|
+
};
|
|
47382
|
+
}
|
|
47383
|
+
async function loadLegacySkillsPatch() {
|
|
47384
|
+
const skillsRoot = resolveLegacyPath(LEGACY_SKILLS_DIR);
|
|
47385
|
+
const reposRaw = await readJsonFileIfExists(nodePath.join(skillsRoot, LEGACY_SKILLS_REPOS_FILE));
|
|
47386
|
+
const installsBySlug = {};
|
|
47387
|
+
let dirEntries = [];
|
|
47388
|
+
try {
|
|
47389
|
+
dirEntries = await promises.readdir(skillsRoot, { withFileTypes: true });
|
|
47390
|
+
} catch (error) {
|
|
47391
|
+
if (error.code !== "ENOENT") throw error;
|
|
47392
|
+
}
|
|
47393
|
+
for (const entry of dirEntries) {
|
|
47394
|
+
if (!entry.isDirectory()) continue;
|
|
47395
|
+
if (entry.name.startsWith(".")) continue;
|
|
47396
|
+
const parsed = parseSkillInstallMetadata(await readJsonFileIfExists(nodePath.join(skillsRoot, entry.name, LEGACY_SKILL_MANIFEST)));
|
|
47397
|
+
if (!parsed) continue;
|
|
47398
|
+
installsBySlug[entry.name] = parsed;
|
|
47399
|
+
}
|
|
47400
|
+
const sources = isRecord$7(reposRaw) && Array.isArray(reposRaw.sources) ? reposRaw.sources : [];
|
|
47401
|
+
if (sources.length === 0 && Object.keys(installsBySlug).length === 0) return {};
|
|
47402
|
+
return { skills: {
|
|
47403
|
+
sources,
|
|
47404
|
+
installsBySlug
|
|
47405
|
+
} };
|
|
47406
|
+
}
|
|
47407
|
+
function mergeLegacyLocalStoragePatch(payload) {
|
|
47408
|
+
const patch = {};
|
|
47409
|
+
const consumedKeys = /* @__PURE__ */ new Set();
|
|
47410
|
+
const skippedKeys = /* @__PURE__ */ new Set();
|
|
47411
|
+
const legacyPayloadKeys = new Set(Object.keys(payload).filter((key) => LEGACY_LOCALSTORAGE_KEYS.includes(key)));
|
|
47412
|
+
const hasKey = (key) => legacyPayloadKeys.has(key);
|
|
47413
|
+
const markSkippedIfPresent = (key, consumed) => {
|
|
47414
|
+
if (!hasKey(key)) return;
|
|
47415
|
+
if (consumed) consumedKeys.add(key);
|
|
47416
|
+
else skippedKeys.add(key);
|
|
47417
|
+
};
|
|
47418
|
+
const settingsStorage = payload["settings-storage"];
|
|
47419
|
+
if (isRecord$7(settingsStorage)) {
|
|
47420
|
+
const nextExcludeFolders = Array.isArray(settingsStorage.excludeFolders) ? settingsStorage.excludeFolders.filter((item) => typeof item === "string") : void 0;
|
|
47421
|
+
const nextBeep = typeof settingsStorage.enableTaskCompleteBeep === "boolean" ? settingsStorage.enableTaskCompleteBeep : void 0;
|
|
47422
|
+
const nextSleep = typeof settingsStorage.preventSleepDuringTasks === "boolean" ? settingsStorage.preventSleepDuringTasks : void 0;
|
|
47423
|
+
patch.preferences = {
|
|
47424
|
+
excludeFolders: nextExcludeFolders,
|
|
47425
|
+
enableTaskCompleteBeep: nextBeep,
|
|
47426
|
+
preventSleepDuringTasks: nextSleep
|
|
47427
|
+
};
|
|
47428
|
+
markSkippedIfPresent("settings-storage", nextExcludeFolders !== void 0 || nextBeep !== void 0 || nextSleep !== void 0);
|
|
47429
|
+
} else markSkippedIfPresent("settings-storage", false);
|
|
47430
|
+
markSkippedIfPresent("provider", hasKey("provider"));
|
|
47431
|
+
markSkippedIfPresent("sandbox-storage", hasKey("sandbox-storage"));
|
|
47432
|
+
const projectSettings = payload["project-settings-storage"];
|
|
47433
|
+
if (isRecord$7(projectSettings) && isRecord$7(projectSettings.settingsByPath)) {
|
|
47434
|
+
patch.workspaceSettingsByPath = projectSettings.settingsByPath;
|
|
47435
|
+
markSkippedIfPresent("project-settings-storage", true);
|
|
47436
|
+
} else markSkippedIfPresent("project-settings-storage", false);
|
|
47437
|
+
const folder = payload["folder-storage"];
|
|
47438
|
+
if (isRecord$7(folder)) {
|
|
47439
|
+
const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(isRecord$7) : void 0;
|
|
47440
|
+
const pinnedPaths = Array.isArray(folder.pinnedPaths) ? folder.pinnedPaths.filter((item) => typeof item === "string") : void 0;
|
|
47441
|
+
patch.preferences = {
|
|
47442
|
+
...patch.preferences ?? {},
|
|
47443
|
+
folderHistory,
|
|
47444
|
+
pinnedPaths
|
|
47445
|
+
};
|
|
47446
|
+
markSkippedIfPresent("folder-storage", folderHistory !== void 0 || pinnedPaths !== void 0);
|
|
47447
|
+
} else markSkippedIfPresent("folder-storage", false);
|
|
47448
|
+
const categories = payload["conversation-categories-storage"];
|
|
47449
|
+
let consumedCategories = false;
|
|
47450
|
+
if (isRecord$7(categories)) {
|
|
47451
|
+
if (isRecord$7(categories.categoriesByCwd)) {
|
|
47452
|
+
patch.conversationCategoriesByCwd = categories.categoriesByCwd;
|
|
47453
|
+
consumedCategories = true;
|
|
47454
|
+
}
|
|
47455
|
+
if (isRecord$7(categories.conversationCategoryByCwd)) {
|
|
47456
|
+
patch.conversationCategoryAssignmentsByCwd = categories.conversationCategoryByCwd;
|
|
47457
|
+
consumedCategories = true;
|
|
47458
|
+
}
|
|
47459
|
+
}
|
|
47460
|
+
markSkippedIfPresent("conversation-categories-storage", consumedCategories);
|
|
47461
|
+
const legacyAutoRoll = payload["codex:auto-roll-settings"];
|
|
47462
|
+
const autoRoll = pickAutoRoll(legacyAutoRoll);
|
|
47463
|
+
if (autoRoll) {
|
|
47464
|
+
patch.autoRoll = {
|
|
47465
|
+
enabled: autoRoll.enabled,
|
|
47466
|
+
rearmRemainingThreshold: autoRoll.rearmRemainingThreshold,
|
|
47467
|
+
switchRemainingThreshold: autoRoll.switchRemainingThreshold,
|
|
47468
|
+
restartOfficialCodexOnAutoRoll: autoRoll.restartOfficialCodexOnAutoRoll,
|
|
47469
|
+
launchOfficialCodexWhenClosedOnAutoRoll: autoRoll.launchOfficialCodexWhenClosedOnAutoRoll,
|
|
47470
|
+
priorityOrder: autoRoll.priorityOrder,
|
|
47471
|
+
lowRemainingNotificationEnabled: autoRoll.lowRemainingNotificationEnabled,
|
|
47472
|
+
lowRemainingNotificationThreshold: autoRoll.lowRemainingNotificationThreshold
|
|
47473
|
+
};
|
|
47474
|
+
markSkippedIfPresent("codex:auto-roll-settings", true);
|
|
47475
|
+
} else markSkippedIfPresent("codex:auto-roll-settings", false);
|
|
47476
|
+
return {
|
|
47477
|
+
patch,
|
|
47478
|
+
consumedKeys: Array.from(consumedKeys),
|
|
47479
|
+
skippedKeys: Array.from(skippedKeys)
|
|
47480
|
+
};
|
|
47481
|
+
}
|
|
47482
|
+
async function removeIfExists(target) {
|
|
47483
|
+
await promises.rm(target, {
|
|
47484
|
+
recursive: true,
|
|
47485
|
+
force: true
|
|
47486
|
+
});
|
|
47487
|
+
}
|
|
47488
|
+
async function cleanupLegacyCanonicalSources() {
|
|
47489
|
+
const homeDir = resolveHomeDir$1();
|
|
47490
|
+
await removeIfExists(resolveLegacyAppStatePath());
|
|
47491
|
+
await removeIfExists(nodePath.join(getUserDataDir(), LEGACY_APP_SETTINGS_PARITY_FILE));
|
|
47492
|
+
await removeIfExists(nodePath.join(homeDir, SQLITE_STORAGE_DIR));
|
|
47493
|
+
await removeIfExists(resolveLegacyPath(LEGACY_SETTINGS_FILE));
|
|
47494
|
+
await removeIfExists(resolveLegacyPath(LEGACY_SETTINGS_BACKUP_FILE));
|
|
47495
|
+
await removeIfExists(resolveLegacyPath(LEGACY_SYNC_STATE_FILE));
|
|
47496
|
+
await removeIfExists(resolveLegacyPath(LEGACY_LICENSE_SECRET_FILE$1));
|
|
47497
|
+
await removeIfExists(resolveLegacyPath(LEGACY_SKILLS_DIR, LEGACY_SKILLS_REPOS_FILE));
|
|
47498
|
+
const profileHomesRoot = resolveLegacyPath(LEGACY_PROFILE_HOMES_DIR);
|
|
47499
|
+
try {
|
|
47500
|
+
const profileHomes = await promises.readdir(profileHomesRoot, { withFileTypes: true });
|
|
47501
|
+
for (const profileHome of profileHomes) {
|
|
47502
|
+
if (!profileHome.isDirectory()) continue;
|
|
47503
|
+
const profileDir = nodePath.join(profileHomesRoot, profileHome.name);
|
|
47504
|
+
let files = [];
|
|
47505
|
+
try {
|
|
47506
|
+
files = await promises.readdir(profileDir);
|
|
47507
|
+
} catch {
|
|
47508
|
+
continue;
|
|
47509
|
+
}
|
|
47510
|
+
for (const file of files) {
|
|
47511
|
+
if (!file.startsWith("profile.json")) continue;
|
|
47512
|
+
await removeIfExists(nodePath.join(profileDir, file));
|
|
47513
|
+
}
|
|
47514
|
+
}
|
|
47515
|
+
} catch (error) {
|
|
47516
|
+
if (!isMissingPathError(error)) logWarn("Failed cleaning legacy profile metadata:", {
|
|
47517
|
+
profileHomesRoot,
|
|
47518
|
+
error: error instanceof Error ? error.message : String(error)
|
|
47519
|
+
});
|
|
47520
|
+
}
|
|
47521
|
+
const skillsRoot = resolveLegacyPath(LEGACY_SKILLS_DIR);
|
|
47522
|
+
try {
|
|
47523
|
+
const skillDirs = await promises.readdir(skillsRoot, { withFileTypes: true });
|
|
47524
|
+
for (const entry of skillDirs) {
|
|
47525
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
47526
|
+
await removeIfExists(nodePath.join(skillsRoot, entry.name, LEGACY_SKILL_MANIFEST));
|
|
47527
|
+
}
|
|
47528
|
+
} catch (error) {
|
|
47529
|
+
if (!isMissingPathError(error)) logWarn("Failed cleaning legacy skills metadata:", {
|
|
47530
|
+
skillsRoot,
|
|
47531
|
+
error: error instanceof Error ? error.message : String(error)
|
|
47532
|
+
});
|
|
47533
|
+
}
|
|
47534
|
+
}
|
|
47535
|
+
async function runStorageMigrationV1() {
|
|
47536
|
+
const current = await getAppState();
|
|
47537
|
+
if (current.migration.status === "complete") return current;
|
|
47538
|
+
if (current.migration.status === "pending_local_storage") {
|
|
47539
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47540
|
+
return updateAppState((state) => ({
|
|
47541
|
+
...state,
|
|
47542
|
+
migration: {
|
|
47543
|
+
...state.migration,
|
|
47544
|
+
status: "complete",
|
|
47545
|
+
completedAt,
|
|
47546
|
+
lastError: null
|
|
47547
|
+
}
|
|
47548
|
+
}), {
|
|
47549
|
+
mode: "replace",
|
|
47550
|
+
allowBeforeMigrationComplete: true
|
|
47551
|
+
});
|
|
47552
|
+
}
|
|
47553
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47554
|
+
try {
|
|
47555
|
+
await migrateLegacyDirectoriesToUserData();
|
|
47556
|
+
const mergedPatch = (await Promise.all([
|
|
47557
|
+
loadLegacySettingsPatch(),
|
|
47558
|
+
loadLegacySyncPatch(),
|
|
47559
|
+
loadLegacyAppSettingsParityPatch(),
|
|
47560
|
+
loadLegacyProfilesPatch(),
|
|
47561
|
+
loadLegacySkillsPatch()
|
|
47562
|
+
])).reduce((acc, patch) => {
|
|
47563
|
+
return {
|
|
47564
|
+
...acc,
|
|
47565
|
+
...patch,
|
|
47566
|
+
app: {
|
|
47567
|
+
...acc.app ?? {},
|
|
47568
|
+
...patch.app ?? {}
|
|
47569
|
+
},
|
|
47570
|
+
license: {
|
|
47571
|
+
...acc.license ?? {},
|
|
47572
|
+
...patch.license ?? {}
|
|
47573
|
+
},
|
|
47574
|
+
autoRoll: {
|
|
47575
|
+
...acc.autoRoll ?? {},
|
|
47576
|
+
...patch.autoRoll ?? {}
|
|
47577
|
+
},
|
|
47578
|
+
runtimeSettings: {
|
|
47579
|
+
...acc.runtimeSettings ?? {},
|
|
47580
|
+
...patch.runtimeSettings ?? {}
|
|
47581
|
+
},
|
|
47582
|
+
preferences: {
|
|
47583
|
+
...acc.preferences ?? {},
|
|
47584
|
+
...patch.preferences ?? {}
|
|
47585
|
+
},
|
|
47586
|
+
sync: {
|
|
47587
|
+
...acc.sync ?? {},
|
|
47588
|
+
...patch.sync ?? {}
|
|
47589
|
+
},
|
|
47590
|
+
profilesByName: {
|
|
47591
|
+
...acc.profilesByName ?? {},
|
|
47592
|
+
...patch.profilesByName ?? {}
|
|
47593
|
+
},
|
|
47594
|
+
workspaceSettingsByPath: {
|
|
47595
|
+
...acc.workspaceSettingsByPath ?? {},
|
|
47596
|
+
...patch.workspaceSettingsByPath ?? {}
|
|
47597
|
+
},
|
|
47598
|
+
conversationCategoriesByCwd: {
|
|
47599
|
+
...acc.conversationCategoriesByCwd ?? {},
|
|
47600
|
+
...patch.conversationCategoriesByCwd ?? {}
|
|
47601
|
+
},
|
|
47602
|
+
conversationCategoryAssignmentsByCwd: {
|
|
47603
|
+
...acc.conversationCategoryAssignmentsByCwd ?? {},
|
|
47604
|
+
...patch.conversationCategoryAssignmentsByCwd ?? {}
|
|
47605
|
+
},
|
|
47606
|
+
skills: {
|
|
47607
|
+
...acc.skills ?? {},
|
|
47608
|
+
...patch.skills ?? {},
|
|
47609
|
+
sources: patch.skills?.sources ?? acc.skills?.sources,
|
|
47610
|
+
installsBySlug: {
|
|
47611
|
+
...acc.skills?.installsBySlug ?? {},
|
|
47612
|
+
...patch.skills?.installsBySlug ?? {}
|
|
47613
|
+
}
|
|
47614
|
+
}
|
|
47615
|
+
};
|
|
47616
|
+
}, {});
|
|
47617
|
+
return await updateAppState((state) => ({
|
|
47618
|
+
...state,
|
|
47619
|
+
...mergedPatch,
|
|
47620
|
+
app: {
|
|
47621
|
+
...state.app,
|
|
47622
|
+
...mergedPatch.app ?? {}
|
|
47623
|
+
},
|
|
47624
|
+
license: {
|
|
47625
|
+
...state.license,
|
|
47626
|
+
...mergedPatch.license ?? {}
|
|
47627
|
+
},
|
|
47628
|
+
autoRoll: {
|
|
47629
|
+
...state.autoRoll,
|
|
47630
|
+
...mergedPatch.autoRoll ?? {}
|
|
47631
|
+
},
|
|
47632
|
+
runtimeSettings: {
|
|
47633
|
+
...state.runtimeSettings,
|
|
47634
|
+
...mergedPatch.runtimeSettings ?? {}
|
|
47635
|
+
},
|
|
47636
|
+
preferences: {
|
|
47637
|
+
...state.preferences,
|
|
47638
|
+
...mergedPatch.preferences ?? {}
|
|
47639
|
+
},
|
|
47640
|
+
sync: {
|
|
47641
|
+
...state.sync,
|
|
47642
|
+
...mergedPatch.sync ?? {}
|
|
47643
|
+
},
|
|
47644
|
+
profilesByName: {
|
|
47645
|
+
...state.profilesByName,
|
|
47646
|
+
...mergedPatch.profilesByName ?? {}
|
|
47647
|
+
},
|
|
47648
|
+
workspaceSettingsByPath: {
|
|
47649
|
+
...state.workspaceSettingsByPath,
|
|
47650
|
+
...mergedPatch.workspaceSettingsByPath ?? {}
|
|
47651
|
+
},
|
|
47652
|
+
conversationCategoriesByCwd: {
|
|
47653
|
+
...state.conversationCategoriesByCwd,
|
|
47654
|
+
...mergedPatch.conversationCategoriesByCwd ?? {}
|
|
47655
|
+
},
|
|
47656
|
+
conversationCategoryAssignmentsByCwd: {
|
|
47657
|
+
...state.conversationCategoryAssignmentsByCwd,
|
|
47658
|
+
...mergedPatch.conversationCategoryAssignmentsByCwd ?? {}
|
|
47659
|
+
},
|
|
47660
|
+
skills: {
|
|
47661
|
+
...state.skills,
|
|
47662
|
+
...mergedPatch.skills ?? {},
|
|
47663
|
+
installsBySlug: {
|
|
47664
|
+
...state.skills.installsBySlug,
|
|
47665
|
+
...mergedPatch.skills?.installsBySlug ?? {}
|
|
47666
|
+
}
|
|
47667
|
+
},
|
|
47668
|
+
migration: {
|
|
47669
|
+
...state.migration,
|
|
47670
|
+
status: "complete",
|
|
47671
|
+
startedAt: state.migration.startedAt ?? startedAt,
|
|
47672
|
+
completedAt: startedAt,
|
|
47673
|
+
localStorageImportedAt: null,
|
|
47674
|
+
lastError: null
|
|
47675
|
+
}
|
|
47676
|
+
}), {
|
|
47677
|
+
mode: "replace",
|
|
47678
|
+
allowBeforeMigrationComplete: true
|
|
47679
|
+
});
|
|
47680
|
+
} catch (error) {
|
|
47681
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
47682
|
+
await updateAppState((state) => ({
|
|
47683
|
+
...state,
|
|
47684
|
+
migration: {
|
|
47685
|
+
...state.migration,
|
|
47686
|
+
status: "pending",
|
|
47687
|
+
startedAt: state.migration.startedAt ?? startedAt,
|
|
47688
|
+
lastError: message
|
|
47689
|
+
}
|
|
47690
|
+
}), {
|
|
47691
|
+
mode: "replace",
|
|
47692
|
+
allowBeforeMigrationComplete: true
|
|
47693
|
+
});
|
|
47694
|
+
throw error;
|
|
47695
|
+
}
|
|
47696
|
+
}
|
|
47697
|
+
async function importLegacyLocalStorageOnce(payload) {
|
|
47698
|
+
if ((await getAppState()).migration.status === "pending") return {
|
|
47699
|
+
completed: false,
|
|
47700
|
+
importedKeys: [],
|
|
47701
|
+
skippedKeys: []
|
|
47702
|
+
};
|
|
47703
|
+
if (!payload || !isRecord$7(payload)) return {
|
|
47704
|
+
completed: true,
|
|
47705
|
+
importedKeys: [],
|
|
47706
|
+
skippedKeys: []
|
|
47707
|
+
};
|
|
47708
|
+
const { patch, consumedKeys, skippedKeys } = mergeLegacyLocalStoragePatch(payload);
|
|
47709
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47710
|
+
if ((await updateAppState((state) => {
|
|
47711
|
+
return {
|
|
47712
|
+
...state,
|
|
47713
|
+
...patch,
|
|
47714
|
+
app: {
|
|
47715
|
+
...state.app,
|
|
47716
|
+
...patch.app ?? {}
|
|
47717
|
+
},
|
|
47718
|
+
autoRoll: {
|
|
47719
|
+
...state.autoRoll,
|
|
47720
|
+
...patch.autoRoll ?? {}
|
|
47721
|
+
},
|
|
47722
|
+
license: {
|
|
47723
|
+
...state.license,
|
|
47724
|
+
...patch.license ?? {}
|
|
47725
|
+
},
|
|
47726
|
+
preferences: {
|
|
47727
|
+
...state.preferences,
|
|
47728
|
+
...patch.preferences ?? {}
|
|
47729
|
+
},
|
|
47730
|
+
workspaceSettingsByPath: {
|
|
47731
|
+
...state.workspaceSettingsByPath,
|
|
47732
|
+
...patch.workspaceSettingsByPath ?? {}
|
|
47733
|
+
},
|
|
47734
|
+
conversationCategoriesByCwd: {
|
|
47735
|
+
...state.conversationCategoriesByCwd,
|
|
47736
|
+
...patch.conversationCategoriesByCwd ?? {}
|
|
47737
|
+
},
|
|
47738
|
+
conversationCategoryAssignmentsByCwd: {
|
|
47739
|
+
...state.conversationCategoryAssignmentsByCwd,
|
|
47740
|
+
...patch.conversationCategoryAssignmentsByCwd ?? {}
|
|
47741
|
+
},
|
|
47742
|
+
migration: {
|
|
47743
|
+
...state.migration,
|
|
47744
|
+
status: "complete",
|
|
47745
|
+
completedAt,
|
|
47746
|
+
localStorageImportedAt: completedAt,
|
|
47747
|
+
lastError: null
|
|
47748
|
+
}
|
|
47749
|
+
};
|
|
47750
|
+
}, {
|
|
47751
|
+
mode: "replace",
|
|
47752
|
+
allowBeforeMigrationComplete: true
|
|
47753
|
+
})).migration.status !== "complete") return {
|
|
47754
|
+
completed: false,
|
|
47755
|
+
importedKeys: [],
|
|
47756
|
+
skippedKeys: []
|
|
47757
|
+
};
|
|
47758
|
+
await cleanupLegacyCanonicalSources();
|
|
47759
|
+
return {
|
|
47760
|
+
completed: true,
|
|
47761
|
+
importedKeys: consumedKeys,
|
|
47762
|
+
skippedKeys
|
|
47763
|
+
};
|
|
47764
|
+
}
|
|
47765
|
+
//#endregion
|
|
47766
|
+
//#region src/config.ts
|
|
47767
|
+
/**
|
|
47768
|
+
* ServerConfig - Runtime configuration services.
|
|
47769
|
+
*
|
|
47770
|
+
* Defines process-level server configuration and networking helpers used by
|
|
47771
|
+
* startup and runtime layers.
|
|
47772
|
+
*
|
|
47773
|
+
* @module ServerConfig
|
|
47774
|
+
*/
|
|
47775
|
+
const DEFAULT_PORT = 3773;
|
|
47776
|
+
/**
|
|
47777
|
+
* ServerConfig - Service tag for server runtime configuration.
|
|
47778
|
+
*/
|
|
47779
|
+
var ServerConfig$1 = class ServerConfig$1 extends Service()("t3/config/ServerConfig") {
|
|
47780
|
+
static {
|
|
47781
|
+
this.layerTest = (cwd, statedir) => effect(ServerConfig$1, gen(function* () {
|
|
47782
|
+
return {
|
|
47783
|
+
cwd,
|
|
47784
|
+
stateDir: statedir,
|
|
47785
|
+
mode: "web",
|
|
47786
|
+
autoBootstrapProjectFromCwd: false,
|
|
47787
|
+
logWebSocketEvents: false,
|
|
47788
|
+
port: 0,
|
|
47789
|
+
host: void 0,
|
|
47790
|
+
authToken: void 0,
|
|
47791
|
+
keybindingsConfigPath: (yield* Path$1).join(statedir, "keybindings.json"),
|
|
47792
|
+
staticDir: void 0,
|
|
47793
|
+
devUrl: void 0,
|
|
47794
|
+
noBrowser: false
|
|
47795
|
+
};
|
|
47796
|
+
}));
|
|
47797
|
+
}
|
|
47798
|
+
};
|
|
47799
|
+
const resolveStaticDir = fn(function* () {
|
|
47800
|
+
const { join, resolve } = yield* Path$1;
|
|
47801
|
+
const { exists } = yield* FileSystem;
|
|
47802
|
+
const bundledClient = resolve(join(import.meta.dirname, "client"));
|
|
47803
|
+
if (yield* exists(join(bundledClient, "index.html")).pipe(orElseSucceed(() => false))) return bundledClient;
|
|
47804
|
+
const monorepoClient = resolve(join(import.meta.dirname, "../../web/dist"));
|
|
47805
|
+
if (yield* exists(join(monorepoClient, "index.html")).pipe(orElseSucceed(() => false))) return monorepoClient;
|
|
47806
|
+
});
|
|
47807
|
+
//#endregion
|
|
47808
|
+
//#region ../../packages/t3-shared/src/shell.ts
|
|
47809
|
+
const SHELL_ENV_NAME_PATTERN = /^[A-Z0-9_]+$/;
|
|
47810
|
+
function readPathFromLoginShell(shell, execFile = execFileSync) {
|
|
47811
|
+
return readEnvironmentFromLoginShell(shell, ["PATH"], execFile).PATH;
|
|
47812
|
+
}
|
|
47813
|
+
function envCaptureStart(name) {
|
|
47814
|
+
return `__T3CODE_ENV_${name}_START__`;
|
|
47815
|
+
}
|
|
47816
|
+
function envCaptureEnd(name) {
|
|
47817
|
+
return `__T3CODE_ENV_${name}_END__`;
|
|
47818
|
+
}
|
|
47819
|
+
function buildEnvironmentCaptureCommand(names) {
|
|
47820
|
+
return names.map((name) => {
|
|
47821
|
+
if (!SHELL_ENV_NAME_PATTERN.test(name)) throw new Error(`Unsupported environment variable name: ${name}`);
|
|
47822
|
+
return [
|
|
47823
|
+
`printf '%s\\n' '${envCaptureStart(name)}'`,
|
|
47824
|
+
`printenv ${name} || true`,
|
|
47825
|
+
`printf '%s\\n' '${envCaptureEnd(name)}'`
|
|
47826
|
+
].join("; ");
|
|
47827
|
+
}).join("; ");
|
|
47828
|
+
}
|
|
47829
|
+
function extractEnvironmentValue(output, name) {
|
|
47830
|
+
const startMarker = envCaptureStart(name);
|
|
47831
|
+
const endMarker = envCaptureEnd(name);
|
|
47832
|
+
const startIndex = output.indexOf(startMarker);
|
|
47833
|
+
if (startIndex === -1) return void 0;
|
|
47834
|
+
const valueStartIndex = startIndex + startMarker.length;
|
|
47835
|
+
const endIndex = output.indexOf(endMarker, valueStartIndex);
|
|
47836
|
+
if (endIndex === -1) return void 0;
|
|
47837
|
+
let value = output.slice(valueStartIndex, endIndex);
|
|
47838
|
+
if (value.startsWith("\n")) value = value.slice(1);
|
|
47839
|
+
if (value.endsWith("\n")) value = value.slice(0, -1);
|
|
47840
|
+
return value.length > 0 ? value : void 0;
|
|
47841
|
+
}
|
|
47842
|
+
const readEnvironmentFromLoginShell = (shell, names, execFile = execFileSync) => {
|
|
47843
|
+
if (names.length === 0) return {};
|
|
47844
|
+
const output = execFile(shell, ["-ilc", buildEnvironmentCaptureCommand(names)], {
|
|
47845
|
+
encoding: "utf8",
|
|
47846
|
+
timeout: 5e3
|
|
47847
|
+
});
|
|
47848
|
+
const environment = {};
|
|
47849
|
+
for (const name of names) {
|
|
47850
|
+
const value = extractEnvironmentValue(output, name);
|
|
47851
|
+
if (value !== void 0) environment[name] = value;
|
|
47852
|
+
}
|
|
47853
|
+
return environment;
|
|
47854
|
+
};
|
|
47855
|
+
//#endregion
|
|
47856
|
+
//#region src/os-jank.ts
|
|
47857
|
+
function fixPath() {
|
|
47858
|
+
if (process.platform !== "darwin") return;
|
|
47859
|
+
try {
|
|
47860
|
+
const result = readPathFromLoginShell(process.env.SHELL ?? "/bin/zsh");
|
|
47861
|
+
if (result) process.env.PATH = result;
|
|
47862
|
+
} catch {}
|
|
47863
|
+
}
|
|
47864
|
+
const expandHomePath$1 = fn(function* (input) {
|
|
47865
|
+
const { join } = yield* Path$1;
|
|
47866
|
+
if (input === "~") return OS.homedir();
|
|
47867
|
+
if (input.startsWith("~/") || input.startsWith("~\\")) return join(OS.homedir(), input.slice(2));
|
|
47868
|
+
return input;
|
|
47869
|
+
});
|
|
47870
|
+
const resolveStateDir = fn(function* (raw) {
|
|
47871
|
+
const { join, resolve } = yield* Path$1;
|
|
47872
|
+
if (!raw || raw.trim().length === 0) return join(OS.homedir(), ".t3", "userdata");
|
|
47873
|
+
return resolve(yield* expandHomePath$1(raw.trim()));
|
|
47874
|
+
});
|
|
47875
|
+
//#endregion
|
|
47876
|
+
//#region ../../packages/t3-contracts/src/baseSchemas.ts
|
|
47877
|
+
const TrimmedString = Trim;
|
|
47878
|
+
const TrimmedNonEmptyString = TrimmedString.check(isNonEmpty());
|
|
47879
|
+
const NonNegativeInt = Int.check(isGreaterThanOrEqualTo(0));
|
|
47880
|
+
const PositiveInt = Int.check(isGreaterThanOrEqualTo(1));
|
|
47881
|
+
const IsoDateTime = String$1;
|
|
47882
|
+
/**
|
|
47883
|
+
* Construct a branded identifier. Enforces non-empty trimmed strings
|
|
47884
|
+
*/
|
|
47885
|
+
const makeEntityId = (brand$2) => TrimmedNonEmptyString.pipe(brand(brand$2));
|
|
47886
|
+
const ThreadId = makeEntityId("ThreadId");
|
|
47887
|
+
const ProjectId = makeEntityId("ProjectId");
|
|
47888
|
+
const CommandId = makeEntityId("CommandId");
|
|
47889
|
+
const EventId = makeEntityId("EventId");
|
|
47890
|
+
const MessageId = makeEntityId("MessageId");
|
|
47891
|
+
const TurnId = makeEntityId("TurnId");
|
|
47892
|
+
const ProviderItemId = makeEntityId("ProviderItemId");
|
|
47893
|
+
const RuntimeSessionId = makeEntityId("RuntimeSessionId");
|
|
47894
|
+
const RuntimeItemId = makeEntityId("RuntimeItemId");
|
|
47895
|
+
const RuntimeRequestId = makeEntityId("RuntimeRequestId");
|
|
47896
|
+
const RuntimeTaskId = makeEntityId("RuntimeTaskId");
|
|
47897
|
+
const ApprovalRequestId = makeEntityId("ApprovalRequestId");
|
|
47898
|
+
const CheckpointRef = makeEntityId("CheckpointRef");
|
|
47899
|
+
//#endregion
|
|
47900
|
+
//#region ../../packages/t3-contracts/src/terminal.ts
|
|
47901
|
+
const DEFAULT_TERMINAL_ID = "default";
|
|
47902
|
+
const TrimmedNonEmptyStringSchema$3 = TrimmedNonEmptyString;
|
|
47903
|
+
const TerminalColsSchema = Int.check(isGreaterThanOrEqualTo(1)).check(isLessThanOrEqualTo(1e3));
|
|
47904
|
+
const TerminalRowsSchema = Int.check(isGreaterThanOrEqualTo(1)).check(isLessThanOrEqualTo(500));
|
|
47905
|
+
const TerminalIdSchema = TrimmedNonEmptyStringSchema$3.check(isMaxLength(128));
|
|
47906
|
+
const TerminalEnvKeySchema = String$1.check(isPattern(/^[A-Za-z_][A-Za-z0-9_]*$/)).check(isMaxLength(128));
|
|
47907
|
+
const TerminalEnvValueSchema = String$1.check(isMaxLength(8192));
|
|
47908
|
+
const TerminalEnvSchema = Record(TerminalEnvKeySchema, TerminalEnvValueSchema).check(isMaxProperties(128));
|
|
47909
|
+
const TerminalIdWithDefaultSchema = TerminalIdSchema.pipe(withDecodingDefault(() => DEFAULT_TERMINAL_ID));
|
|
47910
|
+
const TerminalThreadInput = Struct({ threadId: TrimmedNonEmptyStringSchema$3 });
|
|
47911
|
+
const TerminalSessionInput = Struct({
|
|
47912
|
+
...TerminalThreadInput.fields,
|
|
47913
|
+
terminalId: TerminalIdWithDefaultSchema
|
|
47914
|
+
});
|
|
47915
|
+
const TerminalOpenInput = Struct({
|
|
47916
|
+
...TerminalSessionInput.fields,
|
|
47917
|
+
cwd: TrimmedNonEmptyStringSchema$3,
|
|
47918
|
+
cols: optional$2(TerminalColsSchema),
|
|
47919
|
+
rows: optional$2(TerminalRowsSchema),
|
|
47920
|
+
env: optional$2(TerminalEnvSchema)
|
|
47921
|
+
});
|
|
47922
|
+
const TerminalWriteInput = Struct({
|
|
47923
|
+
...TerminalSessionInput.fields,
|
|
47924
|
+
data: String$1.check(isNonEmpty()).check(isMaxLength(65536))
|
|
47925
|
+
});
|
|
47926
|
+
const TerminalResizeInput = Struct({
|
|
47927
|
+
...TerminalSessionInput.fields,
|
|
47928
|
+
cols: TerminalColsSchema,
|
|
47929
|
+
rows: TerminalRowsSchema
|
|
47930
|
+
});
|
|
47931
|
+
const TerminalClearInput = TerminalSessionInput;
|
|
47932
|
+
const TerminalRestartInput = Struct({
|
|
47933
|
+
...TerminalSessionInput.fields,
|
|
47934
|
+
cwd: TrimmedNonEmptyStringSchema$3,
|
|
47935
|
+
cols: TerminalColsSchema,
|
|
47936
|
+
rows: TerminalRowsSchema,
|
|
47937
|
+
env: optional$2(TerminalEnvSchema)
|
|
47938
|
+
});
|
|
47939
|
+
const TerminalCloseInput = Struct({
|
|
47940
|
+
...TerminalThreadInput.fields,
|
|
47941
|
+
terminalId: optional$2(TerminalIdSchema),
|
|
47942
|
+
deleteHistory: optional$2(Boolean$2)
|
|
47943
|
+
});
|
|
47944
|
+
const TerminalSessionStatus = Literals([
|
|
47945
|
+
"starting",
|
|
47946
|
+
"running",
|
|
47947
|
+
"exited",
|
|
47948
|
+
"error"
|
|
47949
|
+
]);
|
|
47950
|
+
const TerminalSessionSnapshot = Struct({
|
|
47951
|
+
threadId: String$1.check(isNonEmpty()),
|
|
47952
|
+
terminalId: String$1.check(isNonEmpty()),
|
|
47953
|
+
cwd: String$1.check(isNonEmpty()),
|
|
47954
|
+
status: TerminalSessionStatus,
|
|
47955
|
+
pid: NullOr(Int.check(isGreaterThan(0))),
|
|
47956
|
+
history: String$1,
|
|
47957
|
+
exitCode: NullOr(Int),
|
|
47958
|
+
exitSignal: NullOr(Int),
|
|
47959
|
+
updatedAt: String$1
|
|
47960
|
+
});
|
|
47961
|
+
const TerminalEventBaseSchema = Struct({
|
|
47962
|
+
threadId: String$1.check(isNonEmpty()),
|
|
47963
|
+
terminalId: String$1.check(isNonEmpty()),
|
|
47964
|
+
createdAt: String$1
|
|
47965
|
+
});
|
|
47966
|
+
const TerminalStartedEvent = Struct({
|
|
47967
|
+
...TerminalEventBaseSchema.fields,
|
|
47968
|
+
type: Literal("started"),
|
|
47969
|
+
snapshot: TerminalSessionSnapshot
|
|
47970
|
+
});
|
|
47971
|
+
const TerminalOutputEvent = Struct({
|
|
47972
|
+
...TerminalEventBaseSchema.fields,
|
|
47973
|
+
type: Literal("output"),
|
|
47974
|
+
data: String$1
|
|
47975
|
+
});
|
|
47976
|
+
const TerminalExitedEvent = Struct({
|
|
47977
|
+
...TerminalEventBaseSchema.fields,
|
|
47978
|
+
type: Literal("exited"),
|
|
47979
|
+
exitCode: NullOr(Int),
|
|
47980
|
+
exitSignal: NullOr(Int)
|
|
47981
|
+
});
|
|
47982
|
+
const TerminalErrorEvent = Struct({
|
|
47983
|
+
...TerminalEventBaseSchema.fields,
|
|
47984
|
+
type: Literal("error"),
|
|
47985
|
+
message: String$1.check(isNonEmpty())
|
|
47986
|
+
});
|
|
47987
|
+
const TerminalClearedEvent = Struct({
|
|
47988
|
+
...TerminalEventBaseSchema.fields,
|
|
47989
|
+
type: Literal("cleared")
|
|
47990
|
+
});
|
|
47991
|
+
const TerminalRestartedEvent = Struct({
|
|
47992
|
+
...TerminalEventBaseSchema.fields,
|
|
47993
|
+
type: Literal("restarted"),
|
|
47994
|
+
snapshot: TerminalSessionSnapshot
|
|
47995
|
+
});
|
|
47996
|
+
const TerminalActivityEvent = Struct({
|
|
47997
|
+
...TerminalEventBaseSchema.fields,
|
|
47998
|
+
type: Literal("activity"),
|
|
47999
|
+
hasRunningSubprocess: Boolean$2
|
|
48000
|
+
});
|
|
48001
|
+
const TerminalEvent = Union([
|
|
48002
|
+
TerminalStartedEvent,
|
|
48003
|
+
TerminalOutputEvent,
|
|
48004
|
+
TerminalExitedEvent,
|
|
48005
|
+
TerminalErrorEvent,
|
|
48006
|
+
TerminalClearedEvent,
|
|
48007
|
+
TerminalRestartedEvent,
|
|
48008
|
+
TerminalActivityEvent
|
|
48009
|
+
]);
|
|
48010
|
+
//#endregion
|
|
48011
|
+
//#region ../../packages/t3-contracts/src/model.ts
|
|
48012
|
+
const CODEX_REASONING_EFFORT_OPTIONS = [
|
|
48013
|
+
"xhigh",
|
|
48014
|
+
"high",
|
|
48015
|
+
"medium",
|
|
48016
|
+
"low"
|
|
48017
|
+
];
|
|
48018
|
+
const CodexModelOptions = Struct({
|
|
48019
|
+
reasoningEffort: optional$2(Literals(CODEX_REASONING_EFFORT_OPTIONS)),
|
|
48020
|
+
fastMode: optional$2(Boolean$2)
|
|
48021
|
+
});
|
|
48022
|
+
const ProviderModelOptions = Struct({ codex: optional$2(CodexModelOptions) });
|
|
48023
|
+
const MODEL_OPTIONS_BY_PROVIDER = { codex: [
|
|
48024
|
+
{
|
|
48025
|
+
slug: "gpt-5.5",
|
|
48026
|
+
name: "GPT-5.5"
|
|
48027
|
+
},
|
|
48028
|
+
{
|
|
48029
|
+
slug: "gpt-5.4",
|
|
48030
|
+
name: "GPT-5.4"
|
|
48031
|
+
},
|
|
48032
|
+
{
|
|
48033
|
+
slug: "gpt-5.4-mini",
|
|
48034
|
+
name: "GPT-5.4 Mini"
|
|
48035
|
+
},
|
|
48036
|
+
{
|
|
48037
|
+
slug: "gpt-5.3-codex",
|
|
48038
|
+
name: "GPT-5.3 Codex"
|
|
48039
|
+
},
|
|
48040
|
+
{
|
|
48041
|
+
slug: "gpt-5.3-codex-spark",
|
|
48042
|
+
name: "GPT-5.3 Codex Spark"
|
|
48043
|
+
}
|
|
48044
|
+
] };
|
|
48045
|
+
const DEFAULT_MODEL_BY_PROVIDER = { codex: "gpt-5.5" };
|
|
48046
|
+
const DEFAULT_GIT_TEXT_GENERATION_MODEL = "gpt-5.4-mini";
|
|
48047
|
+
const MODEL_SLUG_ALIASES_BY_PROVIDER = { codex: {
|
|
48048
|
+
"gpt-5-codex": "gpt-5.5",
|
|
48049
|
+
"5.5": "gpt-5.5",
|
|
48050
|
+
"5.4": "gpt-5.4",
|
|
48051
|
+
"5.3": "gpt-5.3-codex",
|
|
48052
|
+
"gpt-5.3": "gpt-5.3-codex",
|
|
48053
|
+
"5.3-spark": "gpt-5.3-codex-spark",
|
|
48054
|
+
"gpt-5.3-spark": "gpt-5.3-codex-spark"
|
|
48055
|
+
} };
|
|
48056
|
+
//#endregion
|
|
48057
|
+
//#region ../../packages/t3-contracts/src/orchestration.ts
|
|
48058
|
+
const ORCHESTRATION_WS_METHODS = {
|
|
48059
|
+
getSnapshot: "orchestration.getSnapshot",
|
|
48060
|
+
getThreadSnapshot: "orchestration.getThreadSnapshot",
|
|
48061
|
+
subscribeShell: "orchestration.subscribeShell",
|
|
48062
|
+
subscribeThread: "orchestration.subscribeThread",
|
|
48063
|
+
syncExternalThreads: "orchestration.syncExternalThreads",
|
|
48064
|
+
dispatchCommand: "orchestration.dispatchCommand",
|
|
48065
|
+
getTurnDiff: "orchestration.getTurnDiff",
|
|
48066
|
+
getFullThreadDiff: "orchestration.getFullThreadDiff",
|
|
48067
|
+
replayEvents: "orchestration.replayEvents"
|
|
48068
|
+
};
|
|
48069
|
+
const ORCHESTRATION_WS_CHANNELS = { domainEvent: "orchestration.domainEvent" };
|
|
48070
|
+
const ProviderKind = Literal("codex");
|
|
48071
|
+
const ProviderApprovalPolicy = Literals([
|
|
48072
|
+
"untrusted",
|
|
48073
|
+
"on-failure",
|
|
48074
|
+
"on-request",
|
|
48075
|
+
"never"
|
|
48076
|
+
]);
|
|
48077
|
+
const ProviderSandboxMode = Literals([
|
|
48078
|
+
"read-only",
|
|
48079
|
+
"workspace-write",
|
|
48080
|
+
"danger-full-access"
|
|
48081
|
+
]);
|
|
48082
|
+
const CodexModelSelection = Struct({
|
|
48083
|
+
provider: Literal("codex"),
|
|
48084
|
+
model: TrimmedNonEmptyString,
|
|
48085
|
+
options: optional$2(CodexModelOptions)
|
|
48086
|
+
});
|
|
48087
|
+
const ModelSelection = CodexModelSelection;
|
|
48088
|
+
const CodexProviderStartOptions$1 = Struct({
|
|
48089
|
+
binaryPath: optional$2(TrimmedNonEmptyString),
|
|
48090
|
+
args: optional$2(String$1),
|
|
48091
|
+
homePath: optional$2(TrimmedNonEmptyString)
|
|
48092
|
+
});
|
|
48093
|
+
const ProviderStartOptions$1 = Struct({ codex: optional$2(CodexProviderStartOptions$1) });
|
|
48094
|
+
const RuntimeMode = Literals(["approval-required", "full-access"]);
|
|
48095
|
+
const DEFAULT_RUNTIME_MODE$2 = "full-access";
|
|
48096
|
+
const ProviderInteractionMode = Literals(["default", "plan"]);
|
|
48097
|
+
const DEFAULT_PROVIDER_INTERACTION_MODE = "default";
|
|
48098
|
+
const ThreadOrigin = Literals(["native", "external-import"]);
|
|
48099
|
+
const DEFAULT_THREAD_ORIGIN = "native";
|
|
48100
|
+
const ProviderRequestKind = Literals([
|
|
48101
|
+
"command",
|
|
48102
|
+
"file-read",
|
|
48103
|
+
"file-change"
|
|
48104
|
+
]);
|
|
48105
|
+
const AssistantDeliveryMode = Literals(["buffered", "streaming"]);
|
|
48106
|
+
const ProviderApprovalDecision = Literals([
|
|
48107
|
+
"accept",
|
|
48108
|
+
"acceptForSession",
|
|
48109
|
+
"decline",
|
|
48110
|
+
"cancel"
|
|
48111
|
+
]);
|
|
48112
|
+
const ProviderUserInputAnswers = Record(String$1, Unknown);
|
|
48113
|
+
function supportsCheckpointingForThreadOrigin(origin) {
|
|
48114
|
+
return origin === "native";
|
|
48115
|
+
}
|
|
48116
|
+
const PROVIDER_SEND_TURN_MAX_INPUT_CHARS = 12e4;
|
|
48117
|
+
const PROVIDER_SEND_TURN_MAX_IMAGE_BYTES = 10 * 1024 * 1024;
|
|
48118
|
+
const PROVIDER_SEND_TURN_MAX_IMAGE_DATA_URL_CHARS = 14e6;
|
|
48119
|
+
const CHAT_ATTACHMENT_ID_MAX_CHARS = 128;
|
|
48120
|
+
const ChatAttachmentId = TrimmedNonEmptyString.check(isMaxLength(CHAT_ATTACHMENT_ID_MAX_CHARS), isPattern(/^[a-z0-9_-]+$/i));
|
|
48121
|
+
const ChatImageAttachment = Struct({
|
|
48122
|
+
type: Literal("image"),
|
|
48123
|
+
id: ChatAttachmentId,
|
|
48124
|
+
name: TrimmedNonEmptyString.check(isMaxLength(255)),
|
|
48125
|
+
mimeType: TrimmedNonEmptyString.check(isMaxLength(100), isPattern(/^image\//i)),
|
|
48126
|
+
sizeBytes: NonNegativeInt.check(isLessThanOrEqualTo(PROVIDER_SEND_TURN_MAX_IMAGE_BYTES))
|
|
48127
|
+
});
|
|
48128
|
+
const UploadChatImageAttachment = Struct({
|
|
48129
|
+
type: Literal("image"),
|
|
48130
|
+
name: TrimmedNonEmptyString.check(isMaxLength(255)),
|
|
48131
|
+
mimeType: TrimmedNonEmptyString.check(isMaxLength(100), isPattern(/^image\//i)),
|
|
48132
|
+
sizeBytes: NonNegativeInt.check(isLessThanOrEqualTo(PROVIDER_SEND_TURN_MAX_IMAGE_BYTES)),
|
|
48133
|
+
dataUrl: TrimmedNonEmptyString.check(isMaxLength(PROVIDER_SEND_TURN_MAX_IMAGE_DATA_URL_CHARS))
|
|
48134
|
+
});
|
|
48135
|
+
const ChatAttachment = Union([ChatImageAttachment]);
|
|
48136
|
+
const UploadChatAttachment = Union([UploadChatImageAttachment]);
|
|
46609
48137
|
const ProjectScriptIcon = Literals([
|
|
46610
48138
|
"play",
|
|
46611
48139
|
"test",
|
|
@@ -48758,6 +50286,8 @@ const WS_METHODS = {
|
|
|
48758
50286
|
rateLimitsRefreshNow: "rateLimits.refreshNow",
|
|
48759
50287
|
licenseGetStatus: "license.getStatus",
|
|
48760
50288
|
licenseActivate: "license.activate",
|
|
50289
|
+
licenseActivationCreate: "license.activation.create",
|
|
50290
|
+
licenseActivationPoll: "license.activation.poll",
|
|
48761
50291
|
syncStatus: "sync.status",
|
|
48762
50292
|
syncPull: "sync.pull",
|
|
48763
50293
|
syncPush: "sync.push",
|
|
@@ -48927,6 +50457,8 @@ const WebSocketRequestBody = Union([
|
|
|
48927
50457
|
tagRequestBody(WS_METHODS.rateLimitsRefreshNow, Struct({})),
|
|
48928
50458
|
tagRequestBody(WS_METHODS.licenseGetStatus, Struct({ force: optional$2(Boolean$2) })),
|
|
48929
50459
|
tagRequestBody(WS_METHODS.licenseActivate, Struct({ licenseKey: TrimmedNonEmptyString })),
|
|
50460
|
+
tagRequestBody(WS_METHODS.licenseActivationCreate, Struct({})),
|
|
50461
|
+
tagRequestBody(WS_METHODS.licenseActivationPoll, Struct({ sessionId: TrimmedNonEmptyString })),
|
|
48930
50462
|
tagRequestBody(WS_METHODS.syncStatus, Struct({})),
|
|
48931
50463
|
tagRequestBody(WS_METHODS.syncPull, Struct({})),
|
|
48932
50464
|
tagRequestBody(WS_METHODS.syncPush, Struct({})),
|
|
@@ -49219,7 +50751,7 @@ const launchDetached = (launch) => gen(function* () {
|
|
|
49219
50751
|
});
|
|
49220
50752
|
const make$9 = gen(function* () {
|
|
49221
50753
|
const open = yield* tryPromise({
|
|
49222
|
-
try: () => import("./open-
|
|
50754
|
+
try: () => import("./open-qeX1IlWK.mjs"),
|
|
49223
50755
|
catch: (cause) => new OpenError({
|
|
49224
50756
|
message: "failed to load browser opener",
|
|
49225
50757
|
cause
|
|
@@ -50063,8 +51595,8 @@ const runMigrations = gen(function* () {
|
|
|
50063
51595
|
//#endregion
|
|
50064
51596
|
//#region src/persistence/Layers/Sqlite.ts
|
|
50065
51597
|
const defaultSqliteClientLoaders = {
|
|
50066
|
-
bun: () => import("./SqliteClient-
|
|
50067
|
-
node: () => import("./NodeSqliteClient-
|
|
51598
|
+
bun: () => import("./SqliteClient-CFZi0MEE.mjs"),
|
|
51599
|
+
node: () => import("./NodeSqliteClient-ColmybgR.mjs")
|
|
50068
51600
|
};
|
|
50069
51601
|
const makeRuntimeSqliteLayer = (config) => gen(function* () {
|
|
50070
51602
|
const loader = defaultSqliteClientLoaders[process.versions.bun !== void 0 ? "bun" : "node"];
|
|
@@ -53286,8 +54818,6 @@ const ThreadRevertedPayload = ThreadRevertedPayload$1;
|
|
|
53286
54818
|
const ThreadActivityAppendedPayload = ThreadActivityAppendedPayload$1;
|
|
53287
54819
|
//#endregion
|
|
53288
54820
|
//#region src/orchestration/projector.ts
|
|
53289
|
-
const MAX_THREAD_MESSAGES = 2e3;
|
|
53290
|
-
const MAX_THREAD_CHECKPOINTS = 500;
|
|
53291
54821
|
function checkpointStatusToLatestTurnState(status) {
|
|
53292
54822
|
if (status === "error") return "error";
|
|
53293
54823
|
if (status === "missing") return "interrupted";
|
|
@@ -53503,7 +55033,7 @@ function projectEvent(model, event) {
|
|
|
53503
55033
|
updatedAt: message.updatedAt,
|
|
53504
55034
|
turnId: message.turnId,
|
|
53505
55035
|
...message.attachments !== void 0 ? { attachments: message.attachments } : {}
|
|
53506
|
-
} : entry) : [...thread.messages, message]).slice(-
|
|
55036
|
+
} : entry) : [...thread.messages, message]).slice(-2e3);
|
|
53507
55037
|
return {
|
|
53508
55038
|
...nextBase,
|
|
53509
55039
|
threads: updateThread(nextBase.threads, payload.threadId, {
|
|
@@ -53560,7 +55090,7 @@ function projectEvent(model, event) {
|
|
|
53560
55090
|
}, event.type, "checkpoint");
|
|
53561
55091
|
const existing = thread.checkpoints.find((entry) => entry.turnId === checkpoint.turnId);
|
|
53562
55092
|
if (existing && existing.status !== "missing" && checkpoint.status === "missing") return nextBase;
|
|
53563
|
-
const checkpoints = [...thread.checkpoints.filter((entry) => entry.turnId !== checkpoint.turnId), checkpoint].toSorted((left, right) => left.checkpointTurnCount - right.checkpointTurnCount).slice(-
|
|
55093
|
+
const checkpoints = [...thread.checkpoints.filter((entry) => entry.turnId !== checkpoint.turnId), checkpoint].toSorted((left, right) => left.checkpointTurnCount - right.checkpointTurnCount).slice(-500);
|
|
53564
55094
|
return {
|
|
53565
55095
|
...nextBase,
|
|
53566
55096
|
threads: updateThread(nextBase.threads, payload.threadId, {
|
|
@@ -53580,9 +55110,9 @@ function projectEvent(model, event) {
|
|
|
53580
55110
|
case "thread.reverted": return decodeForEvent(ThreadRevertedPayload, event.payload, event.type, "payload").pipe(map$5((payload) => {
|
|
53581
55111
|
const thread = nextBase.threads.find((entry) => entry.id === payload.threadId);
|
|
53582
55112
|
if (!thread) return nextBase;
|
|
53583
|
-
const checkpoints = thread.checkpoints.filter((entry) => entry.checkpointTurnCount <= payload.turnCount).toSorted((left, right) => left.checkpointTurnCount - right.checkpointTurnCount).slice(-
|
|
55113
|
+
const checkpoints = thread.checkpoints.filter((entry) => entry.checkpointTurnCount <= payload.turnCount).toSorted((left, right) => left.checkpointTurnCount - right.checkpointTurnCount).slice(-500);
|
|
53584
55114
|
const retainedTurnIds = new Set(checkpoints.map((checkpoint) => checkpoint.turnId));
|
|
53585
|
-
const messages = retainThreadMessagesAfterRevert(thread.messages, retainedTurnIds, payload.turnCount).slice(-
|
|
55115
|
+
const messages = retainThreadMessagesAfterRevert(thread.messages, retainedTurnIds, payload.turnCount).slice(-2e3);
|
|
53586
55116
|
const proposedPlans = retainThreadProposedPlansAfterRevert(thread.proposedPlans, retainedTurnIds).slice(-200);
|
|
53587
55117
|
const activities = retainThreadActivitiesAfterRevert(thread.activities, retainedTurnIds);
|
|
53588
55118
|
const latestCheckpoint = checkpoints.at(-1) ?? null;
|
|
@@ -58085,839 +59615,113 @@ const makeOrchestrationProjectionPipeline = gen(function* () {
|
|
|
58085
59615
|
case "thread.activity-appended": {
|
|
58086
59616
|
const requestId = extractActivityRequestId(event.payload.activity.payload) ?? event.metadata.requestId ?? null;
|
|
58087
59617
|
if (requestId === null) return;
|
|
58088
|
-
const existingRow = yield* projectionPendingApprovalRepository.getByRequestId({ requestId });
|
|
58089
|
-
if (event.payload.activity.kind === "approval.resolved") {
|
|
58090
|
-
const resolvedDecisionRaw = typeof event.payload.activity.payload === "object" && event.payload.activity.payload !== null && "decision" in event.payload.activity.payload ? event.payload.activity.payload.decision : null;
|
|
58091
|
-
const resolvedDecision = resolvedDecisionRaw === "accept" || resolvedDecisionRaw === "acceptForSession" || resolvedDecisionRaw === "decline" || resolvedDecisionRaw === "cancel" ? resolvedDecisionRaw : null;
|
|
58092
|
-
yield* projectionPendingApprovalRepository.upsert({
|
|
58093
|
-
requestId,
|
|
58094
|
-
threadId: isSome(existingRow) ? existingRow.value.threadId : event.payload.threadId,
|
|
58095
|
-
turnId: isSome(existingRow) ? existingRow.value.turnId : event.payload.activity.turnId,
|
|
58096
|
-
status: "resolved",
|
|
58097
|
-
decision: resolvedDecision,
|
|
58098
|
-
createdAt: isSome(existingRow) ? existingRow.value.createdAt : event.payload.activity.createdAt,
|
|
58099
|
-
resolvedAt: event.payload.activity.createdAt
|
|
58100
|
-
});
|
|
58101
|
-
return;
|
|
58102
|
-
}
|
|
58103
|
-
if (isSome(existingRow) && existingRow.value.status === "resolved") return;
|
|
58104
|
-
if (event.payload.activity.kind !== "approval.requested") return;
|
|
58105
|
-
yield* projectionPendingApprovalRepository.upsert({
|
|
58106
|
-
requestId,
|
|
58107
|
-
threadId: event.payload.threadId,
|
|
58108
|
-
turnId: event.payload.activity.turnId,
|
|
58109
|
-
status: "pending",
|
|
58110
|
-
decision: null,
|
|
58111
|
-
createdAt: isSome(existingRow) ? existingRow.value.createdAt : event.payload.activity.createdAt,
|
|
58112
|
-
resolvedAt: null
|
|
58113
|
-
});
|
|
58114
|
-
return;
|
|
58115
|
-
}
|
|
58116
|
-
case "thread.approval-response-requested": {
|
|
58117
|
-
const existingRow = yield* projectionPendingApprovalRepository.getByRequestId({ requestId: event.payload.requestId });
|
|
58118
|
-
yield* projectionPendingApprovalRepository.upsert({
|
|
58119
|
-
requestId: event.payload.requestId,
|
|
58120
|
-
threadId: isSome(existingRow) ? existingRow.value.threadId : event.payload.threadId,
|
|
58121
|
-
turnId: isSome(existingRow) ? existingRow.value.turnId : null,
|
|
58122
|
-
status: "resolved",
|
|
58123
|
-
decision: event.payload.decision,
|
|
58124
|
-
createdAt: isSome(existingRow) ? existingRow.value.createdAt : event.payload.createdAt,
|
|
58125
|
-
resolvedAt: event.payload.createdAt
|
|
58126
|
-
});
|
|
58127
|
-
return;
|
|
58128
|
-
}
|
|
58129
|
-
default: return;
|
|
58130
|
-
}
|
|
58131
|
-
});
|
|
58132
|
-
const projectors = [
|
|
58133
|
-
{
|
|
58134
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.projects,
|
|
58135
|
-
apply: applyProjectsProjection
|
|
58136
|
-
},
|
|
58137
|
-
{
|
|
58138
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.threadMessages,
|
|
58139
|
-
apply: applyThreadMessagesProjection
|
|
58140
|
-
},
|
|
58141
|
-
{
|
|
58142
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.threadProposedPlans,
|
|
58143
|
-
apply: applyThreadProposedPlansProjection
|
|
58144
|
-
},
|
|
58145
|
-
{
|
|
58146
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.threadActivities,
|
|
58147
|
-
apply: applyThreadActivitiesProjection
|
|
58148
|
-
},
|
|
58149
|
-
{
|
|
58150
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.threadSessions,
|
|
58151
|
-
apply: applyThreadSessionsProjection
|
|
58152
|
-
},
|
|
58153
|
-
{
|
|
58154
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.threadTurns,
|
|
58155
|
-
apply: applyThreadTurnsProjection
|
|
58156
|
-
},
|
|
58157
|
-
{
|
|
58158
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.checkpoints,
|
|
58159
|
-
apply: applyCheckpointsProjection
|
|
58160
|
-
},
|
|
58161
|
-
{
|
|
58162
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.pendingApprovals,
|
|
58163
|
-
apply: applyPendingApprovalsProjection
|
|
58164
|
-
},
|
|
58165
|
-
{
|
|
58166
|
-
name: ORCHESTRATION_PROJECTOR_NAMES.threads,
|
|
58167
|
-
apply: applyThreadsProjection
|
|
58168
|
-
}
|
|
58169
|
-
];
|
|
58170
|
-
const runProjectorForEvent = (projector, event) => gen(function* () {
|
|
58171
|
-
const attachmentSideEffects = {
|
|
58172
|
-
deletedThreadIds: /* @__PURE__ */ new Set(),
|
|
58173
|
-
prunedThreadRelativePaths: /* @__PURE__ */ new Map()
|
|
58174
|
-
};
|
|
58175
|
-
yield* sql.withTransaction(projector.apply(event, attachmentSideEffects).pipe(flatMap$2(() => projectionStateRepository.upsert({
|
|
58176
|
-
projector: projector.name,
|
|
58177
|
-
lastAppliedSequence: event.sequence,
|
|
58178
|
-
updatedAt: event.occurredAt
|
|
58179
|
-
}))));
|
|
58180
|
-
yield* runAttachmentSideEffects(attachmentSideEffects).pipe(catch_((cause) => logWarning$1("failed to apply projected attachment side-effects", {
|
|
58181
|
-
projector: projector.name,
|
|
58182
|
-
sequence: event.sequence,
|
|
58183
|
-
eventType: event.type,
|
|
58184
|
-
cause
|
|
58185
|
-
})));
|
|
58186
|
-
});
|
|
58187
|
-
const bootstrapProjector = (projector) => projectionStateRepository.getByProjector({ projector: projector.name }).pipe(flatMap$2((stateRow) => runForEach(eventStore.readFromSequence(isSome(stateRow) ? stateRow.value.lastAppliedSequence : 0), (event) => runProjectorForEvent(projector, event))));
|
|
58188
|
-
const projectEvent = (event) => forEach$1(projectors, (projector) => runProjectorForEvent(projector, event), { concurrency: 1 }).pipe(provideService(FileSystem, fileSystem), provideService(Path$1, path), provideService(ServerConfig$1, serverConfig), asVoid, catchTag("SqlError", (sqlError) => fail$3(toPersistenceSqlError("ProjectionPipeline.projectEvent:query")(sqlError))));
|
|
58189
|
-
return {
|
|
58190
|
-
bootstrap: forEach$1(projectors, bootstrapProjector, { concurrency: 1 }).pipe(provideService(FileSystem, fileSystem), provideService(Path$1, path), provideService(ServerConfig$1, serverConfig), asVoid, tap(() => log$1("orchestration projection pipeline bootstrapped").pipe(annotateLogs({ projectors: projectors.length }))), catchTag("SqlError", (sqlError) => fail$3(toPersistenceSqlError("ProjectionPipeline.bootstrap:query")(sqlError)))),
|
|
58191
|
-
projectEvent
|
|
58192
|
-
};
|
|
58193
|
-
});
|
|
58194
|
-
const OrchestrationProjectionPipelineLive = effect(OrchestrationProjectionPipeline, makeOrchestrationProjectionPipeline).pipe(provideMerge(layer$3), provideMerge(ProjectionProjectRepositoryLive), provideMerge(ProjectionThreadRepositoryLive), provideMerge(ProjectionThreadMessageRepositoryLive), provideMerge(ProjectionThreadProposedPlanRepositoryLive), provideMerge(ProjectionThreadActivityRepositoryLive), provideMerge(ProjectionThreadSessionRepositoryLive), provideMerge(ProjectionTurnRepositoryLive), provideMerge(ProjectionCheckpointRepositoryLive), provideMerge(ProjectionPendingApprovalRepositoryLive), provideMerge(ProjectionStateRepositoryLive));
|
|
58195
|
-
//#endregion
|
|
58196
|
-
//#region ../../packages/contracts/src/settings/chat-scrollback.ts
|
|
58197
|
-
const CHAT_SCROLLBACK_DEFAULT = 200;
|
|
58198
|
-
const CHAT_SCROLLBACK_MIN = 50;
|
|
58199
|
-
const CHAT_SCROLLBACK_MAX = 5e3;
|
|
58200
|
-
function clampChatScrollbackItems(value) {
|
|
58201
|
-
if (!Number.isFinite(value)) return 200;
|
|
58202
|
-
return Math.max(50, Math.min(CHAT_SCROLLBACK_MAX, Math.round(value)));
|
|
58203
|
-
}
|
|
58204
|
-
function normalizeChatHistoryScrollbackItems(value) {
|
|
58205
|
-
if (value === null) return null;
|
|
58206
|
-
if (typeof value === "number" && Number.isFinite(value)) return clampChatScrollbackItems(value);
|
|
58207
|
-
if (typeof value === "string") {
|
|
58208
|
-
const parsed = Number(value);
|
|
58209
|
-
if (Number.isFinite(parsed)) return clampChatScrollbackItems(parsed);
|
|
58210
|
-
}
|
|
58211
|
-
return 200;
|
|
58212
|
-
}
|
|
58213
|
-
//#endregion
|
|
58214
|
-
//#region ../../packages/contracts/src/settings/commit-message-prompt.ts
|
|
58215
|
-
const DEFAULT_COMMIT_MESSAGE_PROMPT = `Generate a concise git commit message for the following changes. Follow conventional commit format (e.g., feat:, fix:, refactor:, docs:, etc.). Keep the summary line under 72 characters. Only output the commit message, nothing else.
|
|
58216
|
-
|
|
58217
|
-
Changes:
|
|
58218
|
-
{diff}`;
|
|
58219
|
-
function normalizeLineEndings$1(value) {
|
|
58220
|
-
return value.replace(/\r\n/g, "\n");
|
|
58221
|
-
}
|
|
58222
|
-
function normalizeCommitMessagePrompt(value) {
|
|
58223
|
-
if (typeof value !== "string") return null;
|
|
58224
|
-
const normalized = normalizeLineEndings$1(value).trim();
|
|
58225
|
-
return normalized.length > 0 ? normalized : null;
|
|
58226
|
-
}
|
|
58227
|
-
//#endregion
|
|
58228
|
-
//#region ../../packages/contracts/src/settings/auto-roll.ts
|
|
58229
|
-
const DEFAULT_AUTO_ROLL_ENABLED = false;
|
|
58230
|
-
const DEFAULT_AUTO_ROLL_REARM_REMAINING_THRESHOLD = 15;
|
|
58231
|
-
const DEFAULT_AUTO_ROLL_SWITCH_REMAINING_THRESHOLD = 5;
|
|
58232
|
-
const DEFAULT_RESTART_OFFICIAL_CODEX_ON_AUTO_ROLL = false;
|
|
58233
|
-
const DEFAULT_LAUNCH_OFFICIAL_CODEX_WHEN_CLOSED_ON_AUTO_ROLL = false;
|
|
58234
|
-
const DEFAULT_AUTO_ROLL_PRIORITY_ORDER = [];
|
|
58235
|
-
const DEFAULT_LOW_REMAINING_NOTIFICATION_ENABLED = false;
|
|
58236
|
-
const DEFAULT_LOW_REMAINING_NOTIFICATION_THRESHOLD = 1;
|
|
58237
|
-
const AUTO_ROLL_SWITCH_REMAINING_MIN = 0;
|
|
58238
|
-
const AUTO_ROLL_SWITCH_REMAINING_MAX = 50;
|
|
58239
|
-
const AUTO_ROLL_REARM_REMAINING_MAX = 100;
|
|
58240
|
-
const LOW_REMAINING_NOTIFICATION_MIN = 1;
|
|
58241
|
-
const LOW_REMAINING_NOTIFICATION_MAX = 50;
|
|
58242
|
-
function clampNumber(value, min, max) {
|
|
58243
|
-
return Math.min(max, Math.max(min, value));
|
|
58244
|
-
}
|
|
58245
|
-
function resolveFiniteNumber(value, fallback) {
|
|
58246
|
-
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
58247
|
-
}
|
|
58248
|
-
function legacyUsedThresholdToRemaining(value, fallbackUsed) {
|
|
58249
|
-
return 100 - clampNumber(resolveFiniteNumber(value, fallbackUsed), 0, 100);
|
|
58250
|
-
}
|
|
58251
|
-
function sanitizeAutoRollSwitchRemainingThreshold(value) {
|
|
58252
|
-
return clampNumber(resolveFiniteNumber(value, 5), 0, 50);
|
|
58253
|
-
}
|
|
58254
|
-
function sanitizeAutoRollRearmRemainingThreshold(value, switchRemainingThreshold) {
|
|
58255
|
-
const sanitizedSwitch = sanitizeAutoRollSwitchRemainingThreshold(switchRemainingThreshold);
|
|
58256
|
-
return clampNumber(resolveFiniteNumber(value, 15), sanitizedSwitch + 1, 100);
|
|
58257
|
-
}
|
|
58258
|
-
function sanitizeAutoRollThresholds(rearmRemainingThreshold, switchRemainingThreshold) {
|
|
58259
|
-
const sanitizedSwitch = sanitizeAutoRollSwitchRemainingThreshold(switchRemainingThreshold);
|
|
58260
|
-
return {
|
|
58261
|
-
rearmRemainingThreshold: sanitizeAutoRollRearmRemainingThreshold(rearmRemainingThreshold, sanitizedSwitch),
|
|
58262
|
-
switchRemainingThreshold: sanitizedSwitch
|
|
58263
|
-
};
|
|
58264
|
-
}
|
|
58265
|
-
function sanitizeAutoRollPriorityOrder(value) {
|
|
58266
|
-
if (!Array.isArray(value)) return [...DEFAULT_AUTO_ROLL_PRIORITY_ORDER];
|
|
58267
|
-
const seen = /* @__PURE__ */ new Set();
|
|
58268
|
-
const normalized = [];
|
|
58269
|
-
for (const item of value) {
|
|
58270
|
-
if (typeof item !== "string") continue;
|
|
58271
|
-
const trimmed = item.trim();
|
|
58272
|
-
if (!trimmed || seen.has(trimmed)) continue;
|
|
58273
|
-
seen.add(trimmed);
|
|
58274
|
-
normalized.push(trimmed);
|
|
58275
|
-
}
|
|
58276
|
-
return normalized;
|
|
58277
|
-
}
|
|
58278
|
-
function sanitizeLowRemainingNotificationThreshold(value) {
|
|
58279
|
-
return clampNumber(resolveFiniteNumber(value, 1), 1, 50);
|
|
58280
|
-
}
|
|
58281
|
-
function normalizeAutoRollSettings(raw) {
|
|
58282
|
-
const enabled = typeof raw?.enabled === "boolean" ? raw.enabled : false;
|
|
58283
|
-
const rawSwitchRemaining = typeof raw?.switchRemainingThreshold === "number" ? raw.switchRemainingThreshold : legacyUsedThresholdToRemaining(raw?.switchThreshold, 95);
|
|
58284
|
-
const { rearmRemainingThreshold: normalizedRearm, switchRemainingThreshold: normalizedSwitch } = sanitizeAutoRollThresholds(typeof raw?.rearmRemainingThreshold === "number" ? raw.rearmRemainingThreshold : legacyUsedThresholdToRemaining(raw?.warningThreshold, 85), rawSwitchRemaining);
|
|
58285
|
-
return {
|
|
58286
|
-
enabled,
|
|
58287
|
-
rearmRemainingThreshold: normalizedRearm,
|
|
58288
|
-
switchRemainingThreshold: normalizedSwitch,
|
|
58289
|
-
restartOfficialCodexOnAutoRoll: raw?.restartOfficialCodexOnAutoRoll === true ? true : false,
|
|
58290
|
-
launchOfficialCodexWhenClosedOnAutoRoll: raw?.launchOfficialCodexWhenClosedOnAutoRoll === true ? true : false,
|
|
58291
|
-
priorityOrder: sanitizeAutoRollPriorityOrder(raw?.priorityOrder),
|
|
58292
|
-
lowRemainingNotificationEnabled: raw?.lowRemainingNotificationEnabled === true ? true : false,
|
|
58293
|
-
lowRemainingNotificationThreshold: sanitizeLowRemainingNotificationThreshold(typeof raw?.lowRemainingNotificationThreshold === "number" ? raw.lowRemainingNotificationThreshold : NaN)
|
|
58294
|
-
};
|
|
58295
|
-
}
|
|
58296
|
-
//#endregion
|
|
58297
|
-
//#region ../../packages/runtime-app-state/src/storage/documents.ts
|
|
58298
|
-
const APP_STORAGE_TABLE = "app_storage_documents";
|
|
58299
|
-
const APP_STORAGE_DB_DIR = "t3-projects";
|
|
58300
|
-
const APP_STORAGE_DB_NAME = "state.sqlite";
|
|
58301
|
-
const SQLITE_BUSY_TIMEOUT_MS = 5e3;
|
|
58302
|
-
const SQLITE_BUSY_MAX_ATTEMPTS = 3;
|
|
58303
|
-
const SQLITE_BUSY_RETRY_DELAY_MS = 100;
|
|
58304
|
-
const writeQueueByDbPath = /* @__PURE__ */ new Map();
|
|
58305
|
-
const initializedDbPaths = /* @__PURE__ */ new Set();
|
|
58306
|
-
function isRecord$9(value) {
|
|
58307
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
58308
|
-
}
|
|
58309
|
-
function clone$1(value) {
|
|
58310
|
-
return JSON.parse(JSON.stringify(value));
|
|
58311
|
-
}
|
|
58312
|
-
function safeParseJson(raw) {
|
|
58313
|
-
if (typeof raw !== "string" || raw.trim().length === 0) return null;
|
|
58314
|
-
try {
|
|
58315
|
-
return JSON.parse(raw);
|
|
58316
|
-
} catch {
|
|
58317
|
-
return null;
|
|
58318
|
-
}
|
|
58319
|
-
}
|
|
58320
|
-
function sleep(ms) {
|
|
58321
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
58322
|
-
}
|
|
58323
|
-
function isSqliteBusyError(error) {
|
|
58324
|
-
if (!error || typeof error !== "object") return false;
|
|
58325
|
-
const sqliteError = error;
|
|
58326
|
-
const message = typeof sqliteError.message === "string" ? sqliteError.message.toLowerCase() : "";
|
|
58327
|
-
return sqliteError.code === "SQLITE_BUSY" || sqliteError.errno === 5 || message.includes("sqlite_busy") || message.includes("database is locked");
|
|
58328
|
-
}
|
|
58329
|
-
function beginImmediate(db) {
|
|
58330
|
-
db.exec("BEGIN IMMEDIATE");
|
|
58331
|
-
}
|
|
58332
|
-
function commit(db) {
|
|
58333
|
-
db.exec("COMMIT");
|
|
58334
|
-
}
|
|
58335
|
-
function rollback(db) {
|
|
58336
|
-
try {
|
|
58337
|
-
db.exec("ROLLBACK");
|
|
58338
|
-
} catch {}
|
|
58339
|
-
}
|
|
58340
|
-
function useStatement(db, sql, task) {
|
|
58341
|
-
const statement = db.prepare(sql);
|
|
58342
|
-
try {
|
|
58343
|
-
return task(statement);
|
|
58344
|
-
} finally {
|
|
58345
|
-
statement.finalize?.();
|
|
58346
|
-
}
|
|
58347
|
-
}
|
|
58348
|
-
async function withWriteQueue(dbPath, task) {
|
|
58349
|
-
const previous = writeQueueByDbPath.get(dbPath) ?? Promise.resolve();
|
|
58350
|
-
let release;
|
|
58351
|
-
const current = new Promise((resolve) => {
|
|
58352
|
-
release = resolve;
|
|
58353
|
-
});
|
|
58354
|
-
writeQueueByDbPath.set(dbPath, current);
|
|
58355
|
-
await previous;
|
|
58356
|
-
try {
|
|
58357
|
-
return await task();
|
|
58358
|
-
} finally {
|
|
58359
|
-
release?.();
|
|
58360
|
-
if (writeQueueByDbPath.get(dbPath) === current) writeQueueByDbPath.delete(dbPath);
|
|
58361
|
-
}
|
|
58362
|
-
}
|
|
58363
|
-
function applyConnectionPragmas(db) {
|
|
58364
|
-
db.exec(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS};`);
|
|
58365
|
-
db.exec("PRAGMA journal_mode = WAL;");
|
|
58366
|
-
db.exec("PRAGMA foreign_keys = ON;");
|
|
58367
|
-
}
|
|
58368
|
-
function ensureSchema(db, dbPath) {
|
|
58369
|
-
if (initializedDbPaths.has(dbPath)) return;
|
|
58370
|
-
db.exec(`
|
|
58371
|
-
CREATE TABLE IF NOT EXISTS ${APP_STORAGE_TABLE} (
|
|
58372
|
-
namespace TEXT PRIMARY KEY,
|
|
58373
|
-
value_json TEXT NOT NULL,
|
|
58374
|
-
updated_at TEXT NOT NULL
|
|
58375
|
-
)
|
|
58376
|
-
`);
|
|
58377
|
-
initializedDbPaths.add(dbPath);
|
|
58378
|
-
}
|
|
58379
|
-
async function openDatabase(dbPath) {
|
|
58380
|
-
await promises.mkdir(nodePath.dirname(dbPath), { recursive: true });
|
|
58381
|
-
if (process.versions.bun !== void 0) {
|
|
58382
|
-
const database = new (await (Function("return import('bun:sqlite')")())).Database(dbPath);
|
|
58383
|
-
return {
|
|
58384
|
-
exec: database.exec.bind(database),
|
|
58385
|
-
prepare: database.prepare.bind(database),
|
|
58386
|
-
close: database.close.bind(database)
|
|
58387
|
-
};
|
|
58388
|
-
}
|
|
58389
|
-
const database = new (await (Function("return import('node:sqlite')")())).DatabaseSync(dbPath);
|
|
58390
|
-
return {
|
|
58391
|
-
exec: database.exec.bind(database),
|
|
58392
|
-
prepare: database.prepare.bind(database),
|
|
58393
|
-
close: database.close.bind(database)
|
|
58394
|
-
};
|
|
58395
|
-
}
|
|
58396
|
-
async function withDatabase(dbPath, task) {
|
|
58397
|
-
for (let attempt = 1; attempt <= SQLITE_BUSY_MAX_ATTEMPTS; attempt += 1) {
|
|
58398
|
-
const db = await openDatabase(dbPath);
|
|
58399
|
-
try {
|
|
58400
|
-
applyConnectionPragmas(db);
|
|
58401
|
-
ensureSchema(db, dbPath);
|
|
58402
|
-
return task(db);
|
|
58403
|
-
} catch (error) {
|
|
58404
|
-
if (!isSqliteBusyError(error) || attempt >= SQLITE_BUSY_MAX_ATTEMPTS) throw error;
|
|
58405
|
-
} finally {
|
|
58406
|
-
db.close();
|
|
58407
|
-
}
|
|
58408
|
-
await sleep(SQLITE_BUSY_RETRY_DELAY_MS * attempt);
|
|
58409
|
-
}
|
|
58410
|
-
throw new Error("App storage database remained busy after retrying.");
|
|
58411
|
-
}
|
|
58412
|
-
function resolveAppStorageDbPath(userDataDir) {
|
|
58413
|
-
return nodePath.join(userDataDir, APP_STORAGE_DB_DIR, APP_STORAGE_DB_NAME);
|
|
58414
|
-
}
|
|
58415
|
-
async function readDocument(dbPath, namespace, normalize) {
|
|
58416
|
-
return withDatabase(dbPath, (db) => {
|
|
58417
|
-
const row = useStatement(db, `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`, (statement) => statement.get(namespace));
|
|
58418
|
-
const parsed = isRecord$9(row) ? safeParseJson(row.valueJson) : null;
|
|
58419
|
-
if (parsed === null) return null;
|
|
58420
|
-
return normalize(parsed);
|
|
58421
|
-
});
|
|
58422
|
-
}
|
|
58423
|
-
async function writeDocument(dbPath, namespace, value) {
|
|
58424
|
-
return withWriteQueue(dbPath, async () => withDatabase(dbPath, (db) => {
|
|
58425
|
-
const normalizedValue = clone$1(value);
|
|
58426
|
-
beginImmediate(db);
|
|
58427
|
-
try {
|
|
58428
|
-
useStatement(db, `
|
|
58429
|
-
INSERT INTO ${APP_STORAGE_TABLE} (namespace, value_json, updated_at)
|
|
58430
|
-
VALUES (?, ?, ?)
|
|
58431
|
-
ON CONFLICT(namespace)
|
|
58432
|
-
DO UPDATE SET
|
|
58433
|
-
value_json = excluded.value_json,
|
|
58434
|
-
updated_at = excluded.updated_at
|
|
58435
|
-
`, (statement) => statement.run(namespace, JSON.stringify(normalizedValue), (/* @__PURE__ */ new Date()).toISOString()));
|
|
58436
|
-
commit(db);
|
|
58437
|
-
return normalizedValue;
|
|
58438
|
-
} catch (error) {
|
|
58439
|
-
rollback(db);
|
|
58440
|
-
throw error;
|
|
58441
|
-
}
|
|
58442
|
-
}));
|
|
58443
|
-
}
|
|
58444
|
-
async function updateDocument(input) {
|
|
58445
|
-
return withWriteQueue(input.dbPath, async () => withDatabase(input.dbPath, (db) => {
|
|
58446
|
-
beginImmediate(db);
|
|
58447
|
-
try {
|
|
58448
|
-
const row = useStatement(db, `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`, (statement) => statement.get(input.namespace));
|
|
58449
|
-
const current = isRecord$9(row) ? input.normalize(safeParseJson(row.valueJson) ?? input.fallback()) : input.fallback();
|
|
58450
|
-
const next = input.normalize(input.transform(clone$1(current)));
|
|
58451
|
-
useStatement(db, `
|
|
58452
|
-
INSERT INTO ${APP_STORAGE_TABLE} (namespace, value_json, updated_at)
|
|
58453
|
-
VALUES (?, ?, ?)
|
|
58454
|
-
ON CONFLICT(namespace)
|
|
58455
|
-
DO UPDATE SET
|
|
58456
|
-
value_json = excluded.value_json,
|
|
58457
|
-
updated_at = excluded.updated_at
|
|
58458
|
-
`, (statement) => statement.run(input.namespace, JSON.stringify(next), (/* @__PURE__ */ new Date()).toISOString()));
|
|
58459
|
-
commit(db);
|
|
58460
|
-
return clone$1(next);
|
|
58461
|
-
} catch (error) {
|
|
58462
|
-
rollback(db);
|
|
58463
|
-
throw error;
|
|
59618
|
+
const existingRow = yield* projectionPendingApprovalRepository.getByRequestId({ requestId });
|
|
59619
|
+
if (event.payload.activity.kind === "approval.resolved") {
|
|
59620
|
+
const resolvedDecisionRaw = typeof event.payload.activity.payload === "object" && event.payload.activity.payload !== null && "decision" in event.payload.activity.payload ? event.payload.activity.payload.decision : null;
|
|
59621
|
+
const resolvedDecision = resolvedDecisionRaw === "accept" || resolvedDecisionRaw === "acceptForSession" || resolvedDecisionRaw === "decline" || resolvedDecisionRaw === "cancel" ? resolvedDecisionRaw : null;
|
|
59622
|
+
yield* projectionPendingApprovalRepository.upsert({
|
|
59623
|
+
requestId,
|
|
59624
|
+
threadId: isSome(existingRow) ? existingRow.value.threadId : event.payload.threadId,
|
|
59625
|
+
turnId: isSome(existingRow) ? existingRow.value.turnId : event.payload.activity.turnId,
|
|
59626
|
+
status: "resolved",
|
|
59627
|
+
decision: resolvedDecision,
|
|
59628
|
+
createdAt: isSome(existingRow) ? existingRow.value.createdAt : event.payload.activity.createdAt,
|
|
59629
|
+
resolvedAt: event.payload.activity.createdAt
|
|
59630
|
+
});
|
|
59631
|
+
return;
|
|
59632
|
+
}
|
|
59633
|
+
if (isSome(existingRow) && existingRow.value.status === "resolved") return;
|
|
59634
|
+
if (event.payload.activity.kind !== "approval.requested") return;
|
|
59635
|
+
yield* projectionPendingApprovalRepository.upsert({
|
|
59636
|
+
requestId,
|
|
59637
|
+
threadId: event.payload.threadId,
|
|
59638
|
+
turnId: event.payload.activity.turnId,
|
|
59639
|
+
status: "pending",
|
|
59640
|
+
decision: null,
|
|
59641
|
+
createdAt: isSome(existingRow) ? existingRow.value.createdAt : event.payload.activity.createdAt,
|
|
59642
|
+
resolvedAt: null
|
|
59643
|
+
});
|
|
59644
|
+
return;
|
|
59645
|
+
}
|
|
59646
|
+
case "thread.approval-response-requested": {
|
|
59647
|
+
const existingRow = yield* projectionPendingApprovalRepository.getByRequestId({ requestId: event.payload.requestId });
|
|
59648
|
+
yield* projectionPendingApprovalRepository.upsert({
|
|
59649
|
+
requestId: event.payload.requestId,
|
|
59650
|
+
threadId: isSome(existingRow) ? existingRow.value.threadId : event.payload.threadId,
|
|
59651
|
+
turnId: isSome(existingRow) ? existingRow.value.turnId : null,
|
|
59652
|
+
status: "resolved",
|
|
59653
|
+
decision: event.payload.decision,
|
|
59654
|
+
createdAt: isSome(existingRow) ? existingRow.value.createdAt : event.payload.createdAt,
|
|
59655
|
+
resolvedAt: event.payload.createdAt
|
|
59656
|
+
});
|
|
59657
|
+
return;
|
|
59658
|
+
}
|
|
59659
|
+
default: return;
|
|
58464
59660
|
}
|
|
58465
|
-
})
|
|
58466
|
-
|
|
58467
|
-
|
|
58468
|
-
|
|
58469
|
-
|
|
58470
|
-
const APP_STATE_DOCUMENT = "desktop.app-state";
|
|
58471
|
-
const APP_NAME = "codexuse-desktop";
|
|
58472
|
-
let configuredUserDataDir = null;
|
|
58473
|
-
let appStateCache = null;
|
|
58474
|
-
let writeLock = Promise.resolve();
|
|
58475
|
-
const writeLockContext = new AsyncLocalStorage();
|
|
58476
|
-
function isRecord$8(value) {
|
|
58477
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
58478
|
-
}
|
|
58479
|
-
function clone(value) {
|
|
58480
|
-
return JSON.parse(JSON.stringify(value));
|
|
58481
|
-
}
|
|
58482
|
-
function resolveDefaultUserDataDir() {
|
|
58483
|
-
const home = process.env.HOME || process.env.USERPROFILE || nodeOs.homedir();
|
|
58484
|
-
if (!home) throw new Error("Unable to resolve home directory for app state.");
|
|
58485
|
-
if (process.platform === "darwin") return nodePath.join(home, "Library", "Application Support", APP_NAME);
|
|
58486
|
-
if (process.platform === "win32") {
|
|
58487
|
-
const appData = process.env.APPDATA;
|
|
58488
|
-
if (appData) return nodePath.join(appData, APP_NAME);
|
|
58489
|
-
return nodePath.join(home, "AppData", "Roaming", APP_NAME);
|
|
58490
|
-
}
|
|
58491
|
-
return nodePath.join(home, ".config", APP_NAME);
|
|
58492
|
-
}
|
|
58493
|
-
function getUserDataDir() {
|
|
58494
|
-
return configuredUserDataDir ?? resolveDefaultUserDataDir();
|
|
58495
|
-
}
|
|
58496
|
-
function resolveLegacyAppStatePath() {
|
|
58497
|
-
return nodePath.join(getUserDataDir(), LEGACY_APP_STATE_FILE);
|
|
58498
|
-
}
|
|
58499
|
-
function resolveStorageDbPath() {
|
|
58500
|
-
return resolveAppStorageDbPath(getUserDataDir());
|
|
58501
|
-
}
|
|
58502
|
-
function createDefaultAppState() {
|
|
58503
|
-
return {
|
|
58504
|
-
schemaVersion: 1,
|
|
58505
|
-
autoRoll: {
|
|
58506
|
-
enabled: false,
|
|
58507
|
-
rearmRemainingThreshold: 15,
|
|
58508
|
-
switchRemainingThreshold: 5,
|
|
58509
|
-
restartOfficialCodexOnAutoRoll: false,
|
|
58510
|
-
launchOfficialCodexWhenClosedOnAutoRoll: false,
|
|
58511
|
-
priorityOrder: [],
|
|
58512
|
-
lowRemainingNotificationEnabled: false,
|
|
58513
|
-
lowRemainingNotificationThreshold: 1
|
|
58514
|
-
},
|
|
58515
|
-
officialCodex: {
|
|
58516
|
-
lastProfileSwitchAt: null,
|
|
58517
|
-
lastProfileSwitchProfileKey: null,
|
|
58518
|
-
lastVerifiedLaunchAt: null,
|
|
58519
|
-
lastVerifiedLaunchProfileKey: null,
|
|
58520
|
-
lastObservedPid: null,
|
|
58521
|
-
lastRestartStatus: null,
|
|
58522
|
-
lastRestartReason: null,
|
|
58523
|
-
activity: [],
|
|
58524
|
-
instancesByProfileName: {},
|
|
58525
|
-
pendingRestartDebt: null
|
|
59661
|
+
});
|
|
59662
|
+
const projectors = [
|
|
59663
|
+
{
|
|
59664
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.projects,
|
|
59665
|
+
apply: applyProjectsProjection
|
|
58526
59666
|
},
|
|
58527
|
-
|
|
58528
|
-
|
|
58529
|
-
|
|
58530
|
-
lastProfileName: null
|
|
59667
|
+
{
|
|
59668
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.threadMessages,
|
|
59669
|
+
apply: applyThreadMessagesProjection
|
|
58531
59670
|
},
|
|
58532
|
-
|
|
58533
|
-
|
|
58534
|
-
|
|
58535
|
-
lastVerifiedAt: null,
|
|
58536
|
-
nextCheckAt: null,
|
|
58537
|
-
lastVerificationError: null,
|
|
58538
|
-
status: "inactive",
|
|
58539
|
-
signature: null
|
|
59671
|
+
{
|
|
59672
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.threadProposedPlans,
|
|
59673
|
+
apply: applyThreadProposedPlansProjection
|
|
58540
59674
|
},
|
|
58541
|
-
|
|
58542
|
-
|
|
58543
|
-
|
|
58544
|
-
preventSleepDuringTasks: true,
|
|
58545
|
-
chatHistoryScrollbackItems: 200,
|
|
58546
|
-
systemNotificationsEnabled: true,
|
|
58547
|
-
subagentSystemNotificationsEnabled: true,
|
|
58548
|
-
folderHistory: [],
|
|
58549
|
-
pinnedPaths: []
|
|
59675
|
+
{
|
|
59676
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.threadActivities,
|
|
59677
|
+
apply: applyThreadActivitiesProjection
|
|
58550
59678
|
},
|
|
58551
|
-
|
|
58552
|
-
|
|
58553
|
-
|
|
58554
|
-
layout: { sidebarCollapsed: null },
|
|
58555
|
-
profiles: {
|
|
58556
|
-
viewMode: null,
|
|
58557
|
-
sortBy: null,
|
|
58558
|
-
groupBy: null,
|
|
58559
|
-
planFilter: null,
|
|
58560
|
-
healthFilter: null,
|
|
58561
|
-
customGroupFilter: null,
|
|
58562
|
-
toolbarOpen: null,
|
|
58563
|
-
collapsedSections: {}
|
|
58564
|
-
},
|
|
58565
|
-
onboarding: {
|
|
58566
|
-
welcomeCompleted: false,
|
|
58567
|
-
welcomeCompletedAt: null,
|
|
58568
|
-
welcomeResumeStep: null,
|
|
58569
|
-
milestones: {
|
|
58570
|
-
firstProfileAdded: false,
|
|
58571
|
-
secondProfileAdded: false
|
|
58572
|
-
},
|
|
58573
|
-
sessionCount: 0,
|
|
58574
|
-
nudgeCooldowns: {},
|
|
58575
|
-
nudgeDismissCount: {},
|
|
58576
|
-
proUnlockedCelebrated: false
|
|
58577
|
-
},
|
|
58578
|
-
projectThreadSelections: {},
|
|
58579
|
-
duplicateWarningDismissedKey: null,
|
|
58580
|
-
pendingLicenseActivation: false
|
|
59679
|
+
{
|
|
59680
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.threadSessions,
|
|
59681
|
+
apply: applyThreadSessionsProjection
|
|
58581
59682
|
},
|
|
58582
|
-
|
|
58583
|
-
|
|
58584
|
-
|
|
58585
|
-
conversationCategoryAssignmentsByCwd: {},
|
|
58586
|
-
git: { commitMessagePrompt: DEFAULT_COMMIT_MESSAGE_PROMPT },
|
|
58587
|
-
skills: {
|
|
58588
|
-
sources: [],
|
|
58589
|
-
installsBySlug: {}
|
|
59683
|
+
{
|
|
59684
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.threadTurns,
|
|
59685
|
+
apply: applyThreadTurnsProjection
|
|
58590
59686
|
},
|
|
58591
|
-
|
|
58592
|
-
|
|
58593
|
-
|
|
58594
|
-
lastError: null,
|
|
58595
|
-
remoteUpdatedAt: null
|
|
59687
|
+
{
|
|
59688
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.checkpoints,
|
|
59689
|
+
apply: applyCheckpointsProjection
|
|
58596
59690
|
},
|
|
58597
|
-
|
|
58598
|
-
|
|
58599
|
-
|
|
58600
|
-
lastFlushAt: null,
|
|
58601
|
-
lastError: null
|
|
59691
|
+
{
|
|
59692
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.pendingApprovals,
|
|
59693
|
+
apply: applyPendingApprovalsProjection
|
|
58602
59694
|
},
|
|
58603
|
-
|
|
58604
|
-
|
|
58605
|
-
|
|
58606
|
-
startedAt: null,
|
|
58607
|
-
completedAt: null,
|
|
58608
|
-
localStorageImportedAt: null,
|
|
58609
|
-
lastError: null
|
|
58610
|
-
}
|
|
58611
|
-
};
|
|
58612
|
-
}
|
|
58613
|
-
function asString$10(value) {
|
|
58614
|
-
if (typeof value !== "string") return null;
|
|
58615
|
-
const trimmed = value.trim();
|
|
58616
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
58617
|
-
}
|
|
58618
|
-
function asNumberOrNull(value) {
|
|
58619
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
58620
|
-
}
|
|
58621
|
-
function asBooleanOrNull(value) {
|
|
58622
|
-
return typeof value === "boolean" ? value : null;
|
|
58623
|
-
}
|
|
58624
|
-
function normalizeAppState(raw) {
|
|
58625
|
-
const defaults = createDefaultAppState();
|
|
58626
|
-
if (!isRecord$8(raw)) return defaults;
|
|
58627
|
-
const rawAutoRoll = isRecord$8(raw.autoRoll) ? raw.autoRoll : void 0;
|
|
58628
|
-
const merged = clone(deepMerge(defaults, raw));
|
|
58629
|
-
merged.schemaVersion = 1;
|
|
58630
|
-
merged.autoRoll = normalizeAutoRollSettings(rawAutoRoll);
|
|
58631
|
-
if (!isRecord$8(merged.officialCodex)) merged.officialCodex = clone(defaults.officialCodex);
|
|
58632
|
-
merged.officialCodex.lastProfileSwitchAt = asNumberOrNull(merged.officialCodex.lastProfileSwitchAt);
|
|
58633
|
-
merged.officialCodex.lastProfileSwitchProfileKey = asString$10(merged.officialCodex.lastProfileSwitchProfileKey);
|
|
58634
|
-
merged.officialCodex.lastVerifiedLaunchAt = asNumberOrNull(merged.officialCodex.lastVerifiedLaunchAt);
|
|
58635
|
-
merged.officialCodex.lastVerifiedLaunchProfileKey = asString$10(merged.officialCodex.lastVerifiedLaunchProfileKey);
|
|
58636
|
-
merged.officialCodex.lastObservedPid = asNumberOrNull(merged.officialCodex.lastObservedPid);
|
|
58637
|
-
merged.officialCodex.lastRestartStatus = asString$10(merged.officialCodex.lastRestartStatus);
|
|
58638
|
-
merged.officialCodex.lastRestartReason = asString$10(merged.officialCodex.lastRestartReason);
|
|
58639
|
-
merged.officialCodex.activity = Array.isArray(merged.officialCodex.activity) ? merged.officialCodex.activity.filter((entry) => isRecord$8(entry)).map((entry) => ({
|
|
58640
|
-
id: asString$10(entry.id) ?? "",
|
|
58641
|
-
at: asString$10(entry.at) ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
58642
|
-
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",
|
|
58643
|
-
status: asString$10(entry.status) ?? "unknown",
|
|
58644
|
-
reason: asString$10(entry.reason),
|
|
58645
|
-
decisionId: asString$10(entry.decisionId),
|
|
58646
|
-
profileName: asString$10(entry.profileName),
|
|
58647
|
-
sourceProfileName: asString$10(entry.sourceProfileName),
|
|
58648
|
-
targetProfileName: asString$10(entry.targetProfileName),
|
|
58649
|
-
remainingPercent: asNumberOrNull(entry.remainingPercent),
|
|
58650
|
-
threshold: asNumberOrNull(entry.threshold),
|
|
58651
|
-
snapshotAgeMs: asNumberOrNull(entry.snapshotAgeMs),
|
|
58652
|
-
snapshotSource: asString$10(entry.snapshotSource),
|
|
58653
|
-
phase: asString$10(entry.phase),
|
|
58654
|
-
pid: asNumberOrNull(entry.pid),
|
|
58655
|
-
profileKeyHash: asString$10(entry.profileKeyHash),
|
|
58656
|
-
switchVerified: asBooleanOrNull(entry.switchVerified),
|
|
58657
|
-
restartRequested: asBooleanOrNull(entry.restartRequested),
|
|
58658
|
-
restartResult: asString$10(entry.restartResult),
|
|
58659
|
-
observedProfileName: asString$10(entry.observedProfileName),
|
|
58660
|
-
observedProfileKeyHash: asString$10(entry.observedProfileKeyHash),
|
|
58661
|
-
observedProfileMatchSource: asString$10(entry.observedProfileMatchSource)
|
|
58662
|
-
})).filter((entry) => entry.id && entry.at).slice(-50) : [];
|
|
58663
|
-
if (!isRecord$8(merged.officialCodex.instancesByProfileName)) merged.officialCodex.instancesByProfileName = {};
|
|
58664
|
-
else {
|
|
58665
|
-
const nextInstances = {};
|
|
58666
|
-
for (const [key, value] of Object.entries(merged.officialCodex.instancesByProfileName)) {
|
|
58667
|
-
if (!isRecord$8(value)) continue;
|
|
58668
|
-
const profileName = asString$10(value.profileName) ?? asString$10(key);
|
|
58669
|
-
if (!profileName) continue;
|
|
58670
|
-
nextInstances[profileName] = {
|
|
58671
|
-
profileName,
|
|
58672
|
-
profileKey: asString$10(value.profileKey),
|
|
58673
|
-
profileHome: asString$10(value.profileHome),
|
|
58674
|
-
appPath: asString$10(value.appPath),
|
|
58675
|
-
bundleId: asString$10(value.bundleId),
|
|
58676
|
-
pid: asNumberOrNull(value.pid),
|
|
58677
|
-
appServerPid: asNumberOrNull(value.appServerPid),
|
|
58678
|
-
launchedAt: asNumberOrNull(value.launchedAt),
|
|
58679
|
-
lastVerifiedAt: asNumberOrNull(value.lastVerifiedAt),
|
|
58680
|
-
lastStatus: asString$10(value.lastStatus),
|
|
58681
|
-
lastError: asString$10(value.lastError)
|
|
58682
|
-
};
|
|
58683
|
-
}
|
|
58684
|
-
merged.officialCodex.instancesByProfileName = nextInstances;
|
|
58685
|
-
}
|
|
58686
|
-
if (isRecord$8(merged.officialCodex.pendingRestartDebt)) {
|
|
58687
|
-
const debt = merged.officialCodex.pendingRestartDebt;
|
|
58688
|
-
const targetProfileName = asString$10(debt.targetProfileName);
|
|
58689
|
-
merged.officialCodex.pendingRestartDebt = targetProfileName ? {
|
|
58690
|
-
targetProfileName,
|
|
58691
|
-
targetProfileKey: asString$10(debt.targetProfileKey),
|
|
58692
|
-
sourceProfileName: asString$10(debt.sourceProfileName),
|
|
58693
|
-
sourceProfileKey: asString$10(debt.sourceProfileKey),
|
|
58694
|
-
decisionId: asString$10(debt.decisionId),
|
|
58695
|
-
attempts: asNumberOrNull(debt.attempts) ?? 0,
|
|
58696
|
-
lastReason: asString$10(debt.lastReason)
|
|
58697
|
-
} : null;
|
|
58698
|
-
} else merged.officialCodex.pendingRestartDebt = null;
|
|
58699
|
-
merged.app.lastAppVersion = asString$10(merged.app.lastAppVersion);
|
|
58700
|
-
merged.app.pendingUpdateVersion = asString$10(merged.app.pendingUpdateVersion);
|
|
58701
|
-
merged.app.lastProfileName = asString$10(merged.app.lastProfileName);
|
|
58702
|
-
{
|
|
58703
|
-
const allowedAppKeys = new Set(Object.keys(defaults.app));
|
|
58704
|
-
for (const key of Object.keys(merged.app)) if (!allowedAppKeys.has(key)) delete merged.app[key];
|
|
58705
|
-
}
|
|
58706
|
-
merged.license.licenseKey = asString$10(merged.license.licenseKey);
|
|
58707
|
-
merged.license.purchaseEmail = asString$10(merged.license.purchaseEmail);
|
|
58708
|
-
merged.license.lastVerifiedAt = asString$10(merged.license.lastVerifiedAt);
|
|
58709
|
-
merged.license.nextCheckAt = asString$10(merged.license.nextCheckAt);
|
|
58710
|
-
merged.license.lastVerificationError = asString$10(merged.license.lastVerificationError);
|
|
58711
|
-
merged.license.signature = asString$10(merged.license.signature);
|
|
58712
|
-
if (![
|
|
58713
|
-
"inactive",
|
|
58714
|
-
"active",
|
|
58715
|
-
"grace",
|
|
58716
|
-
"error"
|
|
58717
|
-
].includes(merged.license.status)) merged.license.status = "inactive";
|
|
58718
|
-
if (!Array.isArray(merged.preferences.excludeFolders)) merged.preferences.excludeFolders = [];
|
|
58719
|
-
if (typeof merged.preferences.enableTaskCompleteBeep !== "boolean") merged.preferences.enableTaskCompleteBeep = true;
|
|
58720
|
-
if (typeof merged.preferences.preventSleepDuringTasks !== "boolean") merged.preferences.preventSleepDuringTasks = true;
|
|
58721
|
-
merged.preferences.chatHistoryScrollbackItems = normalizeChatHistoryScrollbackItems(merged.preferences.chatHistoryScrollbackItems);
|
|
58722
|
-
if (typeof merged.preferences.systemNotificationsEnabled !== "boolean") merged.preferences.systemNotificationsEnabled = true;
|
|
58723
|
-
if (typeof merged.preferences.subagentSystemNotificationsEnabled !== "boolean") merged.preferences.subagentSystemNotificationsEnabled = true;
|
|
58724
|
-
if (!Array.isArray(merged.preferences.folderHistory)) merged.preferences.folderHistory = [];
|
|
58725
|
-
if (!Array.isArray(merged.preferences.pinnedPaths)) merged.preferences.pinnedPaths = [];
|
|
58726
|
-
{
|
|
58727
|
-
const allowedPreferenceKeys = new Set(Object.keys(defaults.preferences));
|
|
58728
|
-
for (const key of Object.keys(merged.preferences)) if (!allowedPreferenceKeys.has(key)) delete merged.preferences[key];
|
|
58729
|
-
}
|
|
58730
|
-
if (!isRecord$8(merged.runtimeSettings)) merged.runtimeSettings = {};
|
|
58731
|
-
if (!isRecord$8(merged.ui)) merged.ui = clone(defaults.ui);
|
|
58732
|
-
merged.ui.themeMode = merged.ui.themeMode === "light" || merged.ui.themeMode === "dark" ? merged.ui.themeMode : null;
|
|
58733
|
-
if (!isRecord$8(merged.ui.layout)) merged.ui.layout = clone(defaults.ui.layout);
|
|
58734
|
-
if (typeof merged.ui.layout.sidebarCollapsed !== "boolean") merged.ui.layout.sidebarCollapsed = null;
|
|
58735
|
-
if (!isRecord$8(merged.ui.profiles)) merged.ui.profiles = clone(defaults.ui.profiles);
|
|
58736
|
-
merged.ui.profiles.viewMode = merged.ui.profiles.viewMode === "cards" || merged.ui.profiles.viewMode === "compact" ? merged.ui.profiles.viewMode : null;
|
|
58737
|
-
merged.ui.profiles.sortBy = asString$10(merged.ui.profiles.sortBy);
|
|
58738
|
-
merged.ui.profiles.groupBy = asString$10(merged.ui.profiles.groupBy);
|
|
58739
|
-
merged.ui.profiles.planFilter = asString$10(merged.ui.profiles.planFilter);
|
|
58740
|
-
merged.ui.profiles.healthFilter = asString$10(merged.ui.profiles.healthFilter);
|
|
58741
|
-
merged.ui.profiles.customGroupFilter = asString$10(merged.ui.profiles.customGroupFilter);
|
|
58742
|
-
if (typeof merged.ui.profiles.toolbarOpen !== "boolean") merged.ui.profiles.toolbarOpen = null;
|
|
58743
|
-
if (!isRecord$8(merged.ui.profiles.collapsedSections)) merged.ui.profiles.collapsedSections = {};
|
|
58744
|
-
else merged.ui.profiles.collapsedSections = Object.fromEntries(Object.entries(merged.ui.profiles.collapsedSections).flatMap(([key, value]) => {
|
|
58745
|
-
const normalizedKey = asString$10(key);
|
|
58746
|
-
if (!normalizedKey || typeof value !== "boolean") return [];
|
|
58747
|
-
return [[normalizedKey, value]];
|
|
58748
|
-
}));
|
|
58749
|
-
if (!isRecord$8(merged.ui.onboarding)) merged.ui.onboarding = clone(defaults.ui.onboarding);
|
|
58750
|
-
if (typeof merged.ui.onboarding.welcomeCompleted !== "boolean") merged.ui.onboarding.welcomeCompleted = false;
|
|
58751
|
-
if (!Number.isFinite(merged.ui.onboarding.welcomeCompletedAt)) merged.ui.onboarding.welcomeCompletedAt = null;
|
|
58752
|
-
merged.ui.onboarding.welcomeResumeStep = merged.ui.onboarding.welcomeResumeStep === 2 ? 2 : null;
|
|
58753
|
-
if (!isRecord$8(merged.ui.onboarding.milestones)) merged.ui.onboarding.milestones = clone(defaults.ui.onboarding.milestones);
|
|
58754
|
-
if (typeof merged.ui.onboarding.milestones.firstProfileAdded !== "boolean") merged.ui.onboarding.milestones.firstProfileAdded = false;
|
|
58755
|
-
if (typeof merged.ui.onboarding.milestones.secondProfileAdded !== "boolean") merged.ui.onboarding.milestones.secondProfileAdded = false;
|
|
58756
|
-
if (!Number.isFinite(merged.ui.onboarding.sessionCount)) merged.ui.onboarding.sessionCount = 0;
|
|
58757
|
-
if (!isRecord$8(merged.ui.onboarding.nudgeCooldowns)) merged.ui.onboarding.nudgeCooldowns = {};
|
|
58758
|
-
else merged.ui.onboarding.nudgeCooldowns = Object.fromEntries(Object.entries(merged.ui.onboarding.nudgeCooldowns).flatMap(([key, value]) => {
|
|
58759
|
-
const normalizedKey = asString$10(key);
|
|
58760
|
-
if (!normalizedKey || !Number.isFinite(value)) return [];
|
|
58761
|
-
return [[normalizedKey, Number(value)]];
|
|
58762
|
-
}));
|
|
58763
|
-
if (!isRecord$8(merged.ui.onboarding.nudgeDismissCount)) merged.ui.onboarding.nudgeDismissCount = {};
|
|
58764
|
-
else merged.ui.onboarding.nudgeDismissCount = Object.fromEntries(Object.entries(merged.ui.onboarding.nudgeDismissCount).flatMap(([key, value]) => {
|
|
58765
|
-
const normalizedKey = asString$10(key);
|
|
58766
|
-
if (!normalizedKey || !Number.isFinite(value)) return [];
|
|
58767
|
-
return [[normalizedKey, Number(value)]];
|
|
58768
|
-
}));
|
|
58769
|
-
if (typeof merged.ui.onboarding.proUnlockedCelebrated !== "boolean") merged.ui.onboarding.proUnlockedCelebrated = false;
|
|
58770
|
-
if (!isRecord$8(merged.ui.projectThreadSelections)) merged.ui.projectThreadSelections = {};
|
|
58771
|
-
else merged.ui.projectThreadSelections = Object.fromEntries(Object.entries(merged.ui.projectThreadSelections).flatMap(([projectId, threadId]) => {
|
|
58772
|
-
const normalizedProjectId = asString$10(projectId);
|
|
58773
|
-
if (!normalizedProjectId) return [];
|
|
58774
|
-
return [[normalizedProjectId, typeof threadId === "string" && threadId.trim().length > 0 ? threadId.trim() : null]];
|
|
58775
|
-
}));
|
|
58776
|
-
merged.ui.duplicateWarningDismissedKey = asString$10(merged.ui.duplicateWarningDismissedKey);
|
|
58777
|
-
if (typeof merged.ui.pendingLicenseActivation !== "boolean") merged.ui.pendingLicenseActivation = false;
|
|
58778
|
-
{
|
|
58779
|
-
const allowedUiKeys = new Set(Object.keys(defaults.ui));
|
|
58780
|
-
for (const key of Object.keys(merged.ui)) if (!allowedUiKeys.has(key)) delete merged.ui[key];
|
|
58781
|
-
}
|
|
58782
|
-
if (!isRecord$8(merged.profileDashboard)) merged.profileDashboard = clone(defaults.profileDashboard);
|
|
58783
|
-
if (!isRecord$8(merged.profileDashboard.customGroupsByAccountKey)) merged.profileDashboard.customGroupsByAccountKey = {};
|
|
58784
|
-
else merged.profileDashboard.customGroupsByAccountKey = Object.fromEntries(Object.entries(merged.profileDashboard.customGroupsByAccountKey).flatMap(([key, value]) => {
|
|
58785
|
-
const normalizedKey = asString$10(key);
|
|
58786
|
-
const normalizedValue = asString$10(value);
|
|
58787
|
-
if (!normalizedKey || !normalizedValue) return [];
|
|
58788
|
-
return [[normalizedKey, normalizedValue]];
|
|
58789
|
-
}));
|
|
58790
|
-
{
|
|
58791
|
-
const allowedProfileDashboardKeys = new Set(Object.keys(defaults.profileDashboard));
|
|
58792
|
-
for (const key of Object.keys(merged.profileDashboard)) if (!allowedProfileDashboardKeys.has(key)) delete merged.profileDashboard[key];
|
|
58793
|
-
}
|
|
58794
|
-
const legacyProjectSettingsByPath = isRecord$8(raw.projectSettingsByPath) ? raw.projectSettingsByPath : null;
|
|
58795
|
-
if (!isRecord$8(merged.workspaceSettingsByPath)) merged.workspaceSettingsByPath = {};
|
|
58796
|
-
if (legacyProjectSettingsByPath) merged.workspaceSettingsByPath = {
|
|
58797
|
-
...legacyProjectSettingsByPath,
|
|
58798
|
-
...merged.workspaceSettingsByPath
|
|
58799
|
-
};
|
|
58800
|
-
delete merged.projectSettingsByPath;
|
|
58801
|
-
if (!isRecord$8(merged.conversationCategoriesByCwd)) merged.conversationCategoriesByCwd = {};
|
|
58802
|
-
if (!isRecord$8(merged.conversationCategoryAssignmentsByCwd)) merged.conversationCategoryAssignmentsByCwd = {};
|
|
58803
|
-
if (!isRecord$8(merged.git)) merged.git = clone(defaults.git);
|
|
58804
|
-
merged.git.commitMessagePrompt = normalizeCommitMessagePrompt(merged.git.commitMessagePrompt) ?? DEFAULT_COMMIT_MESSAGE_PROMPT;
|
|
58805
|
-
{
|
|
58806
|
-
const allowedGitKeys = new Set(Object.keys(defaults.git));
|
|
58807
|
-
for (const key of Object.keys(merged.git)) if (!allowedGitKeys.has(key)) delete merged.git[key];
|
|
58808
|
-
}
|
|
58809
|
-
if (!isRecord$8(merged.skills)) merged.skills = clone(defaults.skills);
|
|
58810
|
-
if (!Array.isArray(merged.skills.sources)) merged.skills.sources = [];
|
|
58811
|
-
if (!isRecord$8(merged.skills.installsBySlug)) merged.skills.installsBySlug = {};
|
|
58812
|
-
if (!isRecord$8(merged.sync)) merged.sync = clone(defaults.sync);
|
|
58813
|
-
merged.sync.lastPushAt = asString$10(merged.sync.lastPushAt);
|
|
58814
|
-
merged.sync.lastPullAt = asString$10(merged.sync.lastPullAt);
|
|
58815
|
-
merged.sync.lastError = asString$10(merged.sync.lastError);
|
|
58816
|
-
merged.sync.remoteUpdatedAt = asString$10(merged.sync.remoteUpdatedAt);
|
|
58817
|
-
if (!isRecord$8(merged.analytics)) merged.analytics = isRecord$8(merged.telemetry) ? clone(merged.telemetry) : clone(defaults.analytics);
|
|
58818
|
-
merged.analytics.anonymousId = asString$10(merged.analytics.anonymousId);
|
|
58819
|
-
if (!merged.analytics.anonymousId) {
|
|
58820
|
-
const legacyInstallId = asString$10(merged.telemetry?.installId);
|
|
58821
|
-
merged.analytics.anonymousId = legacyInstallId;
|
|
58822
|
-
}
|
|
58823
|
-
if (typeof merged.analytics.enabled !== "boolean") merged.analytics.enabled = true;
|
|
58824
|
-
merged.analytics.lastFlushAt = asString$10(merged.analytics.lastFlushAt);
|
|
58825
|
-
merged.analytics.lastError = asString$10(merged.analytics.lastError);
|
|
58826
|
-
if ("telemetry" in merged) delete merged.telemetry;
|
|
58827
|
-
if (!isRecord$8(merged.profilesByName)) merged.profilesByName = {};
|
|
58828
|
-
if (!isRecord$8(merged.migration)) merged.migration = clone(defaults.migration);
|
|
58829
|
-
if (![
|
|
58830
|
-
"pending",
|
|
58831
|
-
"pending_local_storage",
|
|
58832
|
-
"complete"
|
|
58833
|
-
].includes(merged.migration.status)) merged.migration.status = "pending";
|
|
58834
|
-
merged.migration.startedAt = asString$10(merged.migration.startedAt);
|
|
58835
|
-
merged.migration.completedAt = asString$10(merged.migration.completedAt);
|
|
58836
|
-
merged.migration.localStorageImportedAt = asString$10(merged.migration.localStorageImportedAt);
|
|
58837
|
-
merged.migration.lastError = asString$10(merged.migration.lastError);
|
|
58838
|
-
return merged;
|
|
58839
|
-
}
|
|
58840
|
-
function deepMerge(base, patch) {
|
|
58841
|
-
if (!isRecord$8(base) || !isRecord$8(patch)) return clone(patch ?? base);
|
|
58842
|
-
const next = { ...base };
|
|
58843
|
-
for (const [key, patchValue] of Object.entries(patch)) {
|
|
58844
|
-
if (patchValue === void 0) continue;
|
|
58845
|
-
const currentValue = next[key];
|
|
58846
|
-
if (Array.isArray(patchValue)) {
|
|
58847
|
-
next[key] = clone(patchValue);
|
|
58848
|
-
continue;
|
|
58849
|
-
}
|
|
58850
|
-
if (isRecord$8(currentValue) && isRecord$8(patchValue)) {
|
|
58851
|
-
next[key] = deepMerge(currentValue, patchValue);
|
|
58852
|
-
continue;
|
|
59695
|
+
{
|
|
59696
|
+
name: ORCHESTRATION_PROJECTOR_NAMES.threads,
|
|
59697
|
+
apply: applyThreadsProjection
|
|
58853
59698
|
}
|
|
58854
|
-
|
|
58855
|
-
|
|
58856
|
-
|
|
58857
|
-
|
|
58858
|
-
|
|
58859
|
-
|
|
58860
|
-
|
|
58861
|
-
|
|
58862
|
-
|
|
58863
|
-
|
|
58864
|
-
|
|
58865
|
-
|
|
58866
|
-
|
|
58867
|
-
|
|
58868
|
-
|
|
58869
|
-
|
|
58870
|
-
}
|
|
58871
|
-
async function writeAppStateToStorage(state) {
|
|
58872
|
-
return writeDocument(resolveStorageDbPath(), APP_STATE_DOCUMENT, normalizeAppState(state));
|
|
58873
|
-
}
|
|
58874
|
-
async function ensureInitialized() {
|
|
58875
|
-
if (appStateCache) return appStateCache;
|
|
58876
|
-
appStateCache = await writeAppStateToStorage(await readAppStateFromStorage() ?? await readLegacyAppStateFromDisk() ?? normalizeAppState(null));
|
|
58877
|
-
return clone(appStateCache);
|
|
58878
|
-
}
|
|
58879
|
-
async function withWriteLock(task) {
|
|
58880
|
-
if (writeLockContext.getStore()) return task();
|
|
58881
|
-
const previous = writeLock;
|
|
58882
|
-
let release;
|
|
58883
|
-
writeLock = new Promise((resolve) => {
|
|
58884
|
-
release = resolve;
|
|
58885
|
-
});
|
|
58886
|
-
await previous;
|
|
58887
|
-
try {
|
|
58888
|
-
return await writeLockContext.run(true, task);
|
|
58889
|
-
} finally {
|
|
58890
|
-
if (release) release();
|
|
58891
|
-
}
|
|
58892
|
-
}
|
|
58893
|
-
async function getAppState() {
|
|
58894
|
-
return clone(await ensureInitialized());
|
|
58895
|
-
}
|
|
58896
|
-
async function updateAppState(transform, options = {}) {
|
|
58897
|
-
const mode = options.mode ?? "patch";
|
|
58898
|
-
const allowBeforeMigrationComplete = options.allowBeforeMigrationComplete === true;
|
|
58899
|
-
return withWriteLock(async () => {
|
|
58900
|
-
const nextState = await updateDocument({
|
|
58901
|
-
dbPath: resolveStorageDbPath(),
|
|
58902
|
-
namespace: APP_STATE_DOCUMENT,
|
|
58903
|
-
normalize: normalizeAppState,
|
|
58904
|
-
fallback: createDefaultAppState,
|
|
58905
|
-
transform: (current) => {
|
|
58906
|
-
if (!allowBeforeMigrationComplete && current.migration.status !== "complete") throw new Error("Storage migration is not complete yet.");
|
|
58907
|
-
const transformed = transform(clone(current));
|
|
58908
|
-
return mode === "replace" ? normalizeAppState(transformed) : normalizeAppState(deepMerge(current, transformed));
|
|
58909
|
-
}
|
|
58910
|
-
});
|
|
58911
|
-
appStateCache = nextState;
|
|
58912
|
-
return clone(nextState);
|
|
58913
|
-
});
|
|
58914
|
-
}
|
|
58915
|
-
async function patchAppState(patch) {
|
|
58916
|
-
return updateAppState(() => patch, {
|
|
58917
|
-
mode: "patch",
|
|
58918
|
-
allowBeforeMigrationComplete: false
|
|
59699
|
+
];
|
|
59700
|
+
const runProjectorForEvent = (projector, event) => gen(function* () {
|
|
59701
|
+
const attachmentSideEffects = {
|
|
59702
|
+
deletedThreadIds: /* @__PURE__ */ new Set(),
|
|
59703
|
+
prunedThreadRelativePaths: /* @__PURE__ */ new Map()
|
|
59704
|
+
};
|
|
59705
|
+
yield* sql.withTransaction(projector.apply(event, attachmentSideEffects).pipe(flatMap$2(() => projectionStateRepository.upsert({
|
|
59706
|
+
projector: projector.name,
|
|
59707
|
+
lastAppliedSequence: event.sequence,
|
|
59708
|
+
updatedAt: event.occurredAt
|
|
59709
|
+
}))));
|
|
59710
|
+
yield* runAttachmentSideEffects(attachmentSideEffects).pipe(catch_((cause) => logWarning$1("failed to apply projected attachment side-effects", {
|
|
59711
|
+
projector: projector.name,
|
|
59712
|
+
sequence: event.sequence,
|
|
59713
|
+
eventType: event.type,
|
|
59714
|
+
cause
|
|
59715
|
+
})));
|
|
58919
59716
|
});
|
|
58920
|
-
}
|
|
59717
|
+
const bootstrapProjector = (projector) => projectionStateRepository.getByProjector({ projector: projector.name }).pipe(flatMap$2((stateRow) => runForEach(eventStore.readFromSequence(isSome(stateRow) ? stateRow.value.lastAppliedSequence : 0), (event) => runProjectorForEvent(projector, event))));
|
|
59718
|
+
const projectEvent = (event) => forEach$1(projectors, (projector) => runProjectorForEvent(projector, event), { concurrency: 1 }).pipe(provideService(FileSystem, fileSystem), provideService(Path$1, path), provideService(ServerConfig$1, serverConfig), asVoid, catchTag("SqlError", (sqlError) => fail$3(toPersistenceSqlError("ProjectionPipeline.projectEvent:query")(sqlError))));
|
|
59719
|
+
return {
|
|
59720
|
+
bootstrap: forEach$1(projectors, bootstrapProjector, { concurrency: 1 }).pipe(provideService(FileSystem, fileSystem), provideService(Path$1, path), provideService(ServerConfig$1, serverConfig), asVoid, tap(() => log$1("orchestration projection pipeline bootstrapped").pipe(annotateLogs({ projectors: projectors.length }))), catchTag("SqlError", (sqlError) => fail$3(toPersistenceSqlError("ProjectionPipeline.bootstrap:query")(sqlError)))),
|
|
59721
|
+
projectEvent
|
|
59722
|
+
};
|
|
59723
|
+
});
|
|
59724
|
+
const OrchestrationProjectionPipelineLive = effect(OrchestrationProjectionPipeline, makeOrchestrationProjectionPipeline).pipe(provideMerge(layer$3), provideMerge(ProjectionProjectRepositoryLive), provideMerge(ProjectionThreadRepositoryLive), provideMerge(ProjectionThreadMessageRepositoryLive), provideMerge(ProjectionThreadProposedPlanRepositoryLive), provideMerge(ProjectionThreadActivityRepositoryLive), provideMerge(ProjectionThreadSessionRepositoryLive), provideMerge(ProjectionTurnRepositoryLive), provideMerge(ProjectionCheckpointRepositoryLive), provideMerge(ProjectionPendingApprovalRepositoryLive), provideMerge(ProjectionStateRepositoryLive));
|
|
58921
59725
|
//#endregion
|
|
58922
59726
|
//#region ../../packages/runtime-app-state/src/app/agentChatWorkspace.ts
|
|
58923
59727
|
const AGENT_CHAT_WORKSPACE_DIRNAME = "agent-chat-workspace";
|
|
@@ -58999,7 +59803,7 @@ function asString$9(value) {
|
|
|
58999
59803
|
const trimmed = value.trim();
|
|
59000
59804
|
return trimmed.length > 0 ? trimmed : null;
|
|
59001
59805
|
}
|
|
59002
|
-
function isRecord$
|
|
59806
|
+
function isRecord$6(value) {
|
|
59003
59807
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
59004
59808
|
}
|
|
59005
59809
|
function parseAutoRoll(raw) {
|
|
@@ -59011,7 +59815,7 @@ function parseAutoRoll(raw) {
|
|
|
59011
59815
|
}
|
|
59012
59816
|
}
|
|
59013
59817
|
function parseStoredLicense(raw) {
|
|
59014
|
-
if (!isRecord$
|
|
59818
|
+
if (!isRecord$6(raw)) return null;
|
|
59015
59819
|
const statusCandidate = asString$9(raw.status);
|
|
59016
59820
|
const status = [
|
|
59017
59821
|
"inactive",
|
|
@@ -59093,7 +59897,7 @@ async function readCodexSettingsJsonRaw() {
|
|
|
59093
59897
|
};
|
|
59094
59898
|
}
|
|
59095
59899
|
async function writeCodexSettingsJsonRaw(payload) {
|
|
59096
|
-
if (!isRecord$
|
|
59900
|
+
if (!isRecord$6(payload)) return;
|
|
59097
59901
|
const autoRoll = parseAutoRoll(payload.autoRoll ?? payload.auto_roll);
|
|
59098
59902
|
const license = parseStoredLicense(payload.license);
|
|
59099
59903
|
await patchAppState({
|
|
@@ -59130,17 +59934,17 @@ async function writeCodexSettingsJsonRaw(payload) {
|
|
|
59130
59934
|
folderHistory: Array.isArray(payload.folderHistory) ? payload.folderHistory : void 0,
|
|
59131
59935
|
pinnedPaths: Array.isArray(payload.pinnedPaths) ? payload.pinnedPaths : void 0
|
|
59132
59936
|
},
|
|
59133
|
-
workspaceSettingsByPath: isRecord$
|
|
59134
|
-
conversationCategoriesByCwd: isRecord$
|
|
59135
|
-
conversationCategoryAssignmentsByCwd: isRecord$
|
|
59136
|
-
git: isRecord$
|
|
59137
|
-
sync: isRecord$
|
|
59937
|
+
workspaceSettingsByPath: isRecord$6(payload.workspaceSettingsByPath) ? payload.workspaceSettingsByPath : isRecord$6(payload.projectSettingsByPath) ? payload.projectSettingsByPath : void 0,
|
|
59938
|
+
conversationCategoriesByCwd: isRecord$6(payload.categoriesByCwd) ? payload.categoriesByCwd : void 0,
|
|
59939
|
+
conversationCategoryAssignmentsByCwd: isRecord$6(payload.conversationCategoryByCwd) ? payload.conversationCategoryByCwd : void 0,
|
|
59940
|
+
git: isRecord$6(payload.git) ? payload.git : void 0,
|
|
59941
|
+
sync: isRecord$6(payload.sync) ? payload.sync : void 0
|
|
59138
59942
|
});
|
|
59139
59943
|
}
|
|
59140
59944
|
//#endregion
|
|
59141
59945
|
//#region ../../packages/runtime-profiles/src/license/secret.ts
|
|
59142
59946
|
const LICENSE_SECRET_DOCUMENT = "desktop.license-secret";
|
|
59143
|
-
const LEGACY_LICENSE_SECRET_FILE
|
|
59947
|
+
const LEGACY_LICENSE_SECRET_FILE = "license.secret";
|
|
59144
59948
|
async function generateSecret() {
|
|
59145
59949
|
return crypto$1.randomBytes(32).toString("hex");
|
|
59146
59950
|
}
|
|
@@ -59148,7 +59952,7 @@ function normalizeSecret(value) {
|
|
|
59148
59952
|
return typeof value === "string" ? value.trim() : "";
|
|
59149
59953
|
}
|
|
59150
59954
|
async function readLegacyLicenseSecret() {
|
|
59151
|
-
const legacyPath = nodePath.join(getUserDataDir(), LEGACY_LICENSE_SECRET_FILE
|
|
59955
|
+
const legacyPath = nodePath.join(getUserDataDir(), LEGACY_LICENSE_SECRET_FILE);
|
|
59152
59956
|
try {
|
|
59153
59957
|
return normalizeSecret(await promises.readFile(legacyPath, "utf8"));
|
|
59154
59958
|
} catch (error) {
|
|
@@ -59872,7 +60676,7 @@ function buildCodexCommand$1(binaryPath, args, env) {
|
|
|
59872
60676
|
}
|
|
59873
60677
|
//#endregion
|
|
59874
60678
|
//#region ../../packages/runtime-codex/src/codex/home.ts
|
|
59875
|
-
function resolveHomeDir
|
|
60679
|
+
function resolveHomeDir() {
|
|
59876
60680
|
return process.env.HOME || process.env.USERPROFILE || nodeOs.homedir();
|
|
59877
60681
|
}
|
|
59878
60682
|
function expandHomePrefix(input, homeDir) {
|
|
@@ -59888,10 +60692,10 @@ function normalizePathCandidate(value) {
|
|
|
59888
60692
|
function normalizeCodexHomePath(input) {
|
|
59889
60693
|
const configured = normalizePathCandidate(input);
|
|
59890
60694
|
if (!configured) return null;
|
|
59891
|
-
return nodePath.resolve(expandHomePrefix(configured, resolveHomeDir
|
|
60695
|
+
return nodePath.resolve(expandHomePrefix(configured, resolveHomeDir()));
|
|
59892
60696
|
}
|
|
59893
60697
|
function resolveDefaultCodexHomeDir() {
|
|
59894
|
-
return nodePath.join(resolveHomeDir
|
|
60698
|
+
return nodePath.join(resolveHomeDir(), ".codex");
|
|
59895
60699
|
}
|
|
59896
60700
|
function resolveCodexHomeDir(options) {
|
|
59897
60701
|
return normalizeCodexHomePath(options?.codexHomePath) ?? resolveDefaultCodexHomeDir();
|
|
@@ -59996,26 +60800,8 @@ function buildCliEnv(codexPath, overrides = {}) {
|
|
|
59996
60800
|
return env;
|
|
59997
60801
|
}
|
|
59998
60802
|
//#endregion
|
|
59999
|
-
//#region ../../packages/shared/src/core/logger.ts
|
|
60000
|
-
const isTestEnv = process.env.NODE_ENV === "test" || process.env.VITEST === "true" || process.env.VITEST === "1";
|
|
60001
|
-
function isMocked(fn) {
|
|
60002
|
-
return Boolean(fn && typeof fn === "function" && "mock" in fn);
|
|
60003
|
-
}
|
|
60004
|
-
function logWarn(...args) {
|
|
60005
|
-
if (isTestEnv && !isMocked(console.warn)) return;
|
|
60006
|
-
console.warn(...args);
|
|
60007
|
-
}
|
|
60008
|
-
function logError(...args) {
|
|
60009
|
-
if (isTestEnv && !isMocked(console.error)) return;
|
|
60010
|
-
console.error(...args);
|
|
60011
|
-
}
|
|
60012
|
-
function logInfo(...args) {
|
|
60013
|
-
if (isTestEnv && !isMocked(console.info)) return;
|
|
60014
|
-
console.info(...args);
|
|
60015
|
-
}
|
|
60016
|
-
//#endregion
|
|
60017
60803
|
//#region ../../packages/runtime-codex/src/codex/app-server.ts
|
|
60018
|
-
function isRecord$
|
|
60804
|
+
function isRecord$5(value) {
|
|
60019
60805
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
60020
60806
|
}
|
|
60021
60807
|
function asTrimmedString$2(value) {
|
|
@@ -60044,10 +60830,10 @@ function isInlineImageValue(value) {
|
|
|
60044
60830
|
return normalized.startsWith("data:") || normalized.startsWith("http://") || normalized.startsWith("https://");
|
|
60045
60831
|
}
|
|
60046
60832
|
function normalizeSendUserMessageItem(value) {
|
|
60047
|
-
if (!isRecord$
|
|
60833
|
+
if (!isRecord$5(value)) return null;
|
|
60048
60834
|
const type = asString$8(value.type).trim();
|
|
60049
60835
|
if (!type) return null;
|
|
60050
|
-
const data = isRecord$
|
|
60836
|
+
const data = isRecord$5(value.data) ? value.data : {};
|
|
60051
60837
|
if (type === "text") {
|
|
60052
60838
|
const text = asString$8(data.text ?? value.text);
|
|
60053
60839
|
if (!text.trim()) return null;
|
|
@@ -60082,7 +60868,7 @@ function normalizeTurnInputParams(params) {
|
|
|
60082
60868
|
if (expectedTurnId && !asString$8(params.expectedTurnId).trim()) normalized.expectedTurnId = expectedTurnId;
|
|
60083
60869
|
const turnId = asString$8(params.turnId ?? params.turn_id ?? expectedTurnId).trim();
|
|
60084
60870
|
if (turnId && !asString$8(params.turnId).trim()) normalized.turnId = turnId;
|
|
60085
|
-
const providedInput = Array.isArray(params.input) ? params.input.filter((entry) => isRecord$
|
|
60871
|
+
const providedInput = Array.isArray(params.input) ? params.input.filter((entry) => isRecord$5(entry)) : [];
|
|
60086
60872
|
if (providedInput.length > 0) {
|
|
60087
60873
|
normalized.input = providedInput;
|
|
60088
60874
|
return normalized;
|
|
@@ -60091,7 +60877,7 @@ function normalizeTurnInputParams(params) {
|
|
|
60091
60877
|
if (providedItems.length > 0) {
|
|
60092
60878
|
const input = providedItems.flatMap((item) => {
|
|
60093
60879
|
const type = asString$8(item.type).trim();
|
|
60094
|
-
const data = isRecord$
|
|
60880
|
+
const data = isRecord$5(item.data) ? item.data : item;
|
|
60095
60881
|
if (type === "text") {
|
|
60096
60882
|
const text = asString$8(data.text).trim();
|
|
60097
60883
|
return text ? [{
|
|
@@ -60134,7 +60920,7 @@ function pickMethodKind(method, params) {
|
|
|
60134
60920
|
const normalized = method.toLowerCase();
|
|
60135
60921
|
if (normalized.includes("requestapproval")) return "approval";
|
|
60136
60922
|
if (normalized.includes("requestuserinput")) return "user_input";
|
|
60137
|
-
if (isRecord$
|
|
60923
|
+
if (isRecord$5(params)) {
|
|
60138
60924
|
if ("file_changes" in params || "fileChanges" in params || "grant_root" in params || "grantRoot" in params) return "patch";
|
|
60139
60925
|
if ("command" in params || "parsed_cmd" in params || "parsedCmd" in params || "cwd" in params) return "exec";
|
|
60140
60926
|
}
|
|
@@ -60336,7 +61122,7 @@ var CodexAppServer = class extends EventEmitter {
|
|
|
60336
61122
|
try {
|
|
60337
61123
|
const response = await this.request("addConversationListener", listenerParams);
|
|
60338
61124
|
this.addConversationListenerSupported = true;
|
|
60339
|
-
return isRecord$
|
|
61125
|
+
return isRecord$5(response) ? response : null;
|
|
60340
61126
|
} catch (error) {
|
|
60341
61127
|
if (isMethodUnavailableError(error, "addConversationListener")) {
|
|
60342
61128
|
this.addConversationListenerSupported = false;
|
|
@@ -60351,7 +61137,7 @@ var CodexAppServer = class extends EventEmitter {
|
|
|
60351
61137
|
try {
|
|
60352
61138
|
const response = await this.request("addConversationListener", listenerParams);
|
|
60353
61139
|
this.addConversationListenerSupported = true;
|
|
60354
|
-
return isRecord$
|
|
61140
|
+
return isRecord$5(response) ? response : null;
|
|
60355
61141
|
} catch (resumeError) {
|
|
60356
61142
|
if (isMethodUnavailableError(resumeError, "addConversationListener")) {
|
|
60357
61143
|
this.addConversationListenerSupported = false;
|
|
@@ -60561,7 +61347,7 @@ var CodexAppServer = class extends EventEmitter {
|
|
|
60561
61347
|
listPendingUserInputRequests() {
|
|
60562
61348
|
return [...this.pendingServerRequests.values()].filter((request) => request.kind === "user_input").map((request) => {
|
|
60563
61349
|
const workspaceId = asTrimmedString$2(request.params.workspace_id ?? request.params.workspaceId);
|
|
60564
|
-
const params = isRecord$
|
|
61350
|
+
const params = isRecord$5(request.params.params) ? request.params.params : request.params;
|
|
60565
61351
|
if (!workspaceId) return null;
|
|
60566
61352
|
return {
|
|
60567
61353
|
workspace_id: workspaceId,
|
|
@@ -60674,7 +61460,7 @@ var CodexAppServer = class extends EventEmitter {
|
|
|
60674
61460
|
this.logParseFailure(line, parseError);
|
|
60675
61461
|
return true;
|
|
60676
61462
|
}
|
|
60677
|
-
if (!isRecord$
|
|
61463
|
+
if (!isRecord$5(parsed)) {
|
|
60678
61464
|
logWarn("[app-server] unexpected JSON message", parsed);
|
|
60679
61465
|
return true;
|
|
60680
61466
|
}
|
|
@@ -60763,9 +61549,9 @@ var CodexAppServer = class extends EventEmitter {
|
|
|
60763
61549
|
id: request.id,
|
|
60764
61550
|
kind,
|
|
60765
61551
|
method: request.method,
|
|
60766
|
-
params: isRecord$
|
|
61552
|
+
params: isRecord$5(request.params) ? request.params : {}
|
|
60767
61553
|
});
|
|
60768
|
-
const params = isRecord$
|
|
61554
|
+
const params = isRecord$5(request.params) ? request.params : {};
|
|
60769
61555
|
if (kind === "exec") this.emit("codex:exec-command-request", {
|
|
60770
61556
|
requestToken: token,
|
|
60771
61557
|
params
|
|
@@ -66784,12 +67570,12 @@ function decodeProviderKind(providerName, operation) {
|
|
|
66784
67570
|
detail: `Unknown persisted provider '${providerName}'.`
|
|
66785
67571
|
}));
|
|
66786
67572
|
}
|
|
66787
|
-
function isRecord$
|
|
67573
|
+
function isRecord$4(value) {
|
|
66788
67574
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
66789
67575
|
}
|
|
66790
67576
|
function mergeRuntimePayload(existing, next) {
|
|
66791
67577
|
if (next === void 0) return existing ?? null;
|
|
66792
|
-
if (isRecord$
|
|
67578
|
+
if (isRecord$4(existing) && isRecord$4(next)) return {
|
|
66793
67579
|
...existing,
|
|
66794
67580
|
...next
|
|
66795
67581
|
};
|
|
@@ -72807,7 +73593,7 @@ const FALLBACK_FEATURE_KEYS = [
|
|
|
72807
73593
|
];
|
|
72808
73594
|
let metadataCache = null;
|
|
72809
73595
|
let metadataCacheAt = 0;
|
|
72810
|
-
function isRecord$
|
|
73596
|
+
function isRecord$3(value) {
|
|
72811
73597
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
72812
73598
|
}
|
|
72813
73599
|
function uniqueSorted(values) {
|
|
@@ -72878,14 +73664,14 @@ function parseFeatureCatalog(output) {
|
|
|
72878
73664
|
}
|
|
72879
73665
|
function parseSchemaKeys(schemaRaw) {
|
|
72880
73666
|
const parsed = JSON.parse(schemaRaw);
|
|
72881
|
-
if (!isRecord$
|
|
73667
|
+
if (!isRecord$3(parsed)) return {
|
|
72882
73668
|
topLevelKeys: FALLBACK_SCHEMA_TOP_LEVEL_KEYS,
|
|
72883
73669
|
featureKeys: FALLBACK_FEATURE_KEYS
|
|
72884
73670
|
};
|
|
72885
|
-
const properties = isRecord$
|
|
73671
|
+
const properties = isRecord$3(parsed.properties) ? parsed.properties : {};
|
|
72886
73672
|
const topLevelKeys = uniqueSorted(Object.keys(properties));
|
|
72887
|
-
const features = isRecord$
|
|
72888
|
-
const featureProperties = isRecord$
|
|
73673
|
+
const features = isRecord$3(properties.features) ? properties.features : {};
|
|
73674
|
+
const featureProperties = isRecord$3(features.properties) ? features.properties : {};
|
|
72889
73675
|
const featureKeys = uniqueSorted(Object.keys(featureProperties));
|
|
72890
73676
|
return {
|
|
72891
73677
|
topLevelKeys: topLevelKeys.length > 0 ? topLevelKeys : FALLBACK_SCHEMA_TOP_LEVEL_KEYS,
|
|
@@ -73636,7 +74422,7 @@ const ACTIVATION_PROMPT = "Reply with exactly: ok.";
|
|
|
73636
74422
|
const ACTIVATION_MODEL = "gpt-5.1-codex-mini";
|
|
73637
74423
|
const MAX_STDERR_CAPTURE_CHARS = 32768;
|
|
73638
74424
|
const REFRESH_TOKEN_REDEEMED_SNIPPET$1 = "refresh token was already used";
|
|
73639
|
-
function isRecord$
|
|
74425
|
+
function isRecord$2(value) {
|
|
73640
74426
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
73641
74427
|
}
|
|
73642
74428
|
function asString$3(value) {
|
|
@@ -73709,35 +74495,35 @@ function createRpcMessageReader(rl) {
|
|
|
73709
74495
|
};
|
|
73710
74496
|
}
|
|
73711
74497
|
function readThreadIdFromResult(result) {
|
|
73712
|
-
if (!isRecord$
|
|
73713
|
-
const value = asString$3((isRecord$
|
|
74498
|
+
if (!isRecord$2(result)) return null;
|
|
74499
|
+
const value = asString$3((isRecord$2(result.thread) ? result.thread : {}).id ?? result.threadId).trim();
|
|
73714
74500
|
return value.length > 0 ? value : null;
|
|
73715
74501
|
}
|
|
73716
74502
|
function readTurnIdFromResult(result) {
|
|
73717
|
-
if (!isRecord$
|
|
73718
|
-
const value = asString$3((isRecord$
|
|
74503
|
+
if (!isRecord$2(result)) return null;
|
|
74504
|
+
const value = asString$3((isRecord$2(result.turn) ? result.turn : {}).id ?? result.turnId).trim();
|
|
73719
74505
|
return value.length > 0 ? value : null;
|
|
73720
74506
|
}
|
|
73721
74507
|
function readTurnIdFromNotification(message) {
|
|
73722
|
-
if (!isRecord$
|
|
73723
|
-
const value = asString$3((isRecord$
|
|
74508
|
+
if (!isRecord$2(message.params)) return null;
|
|
74509
|
+
const value = asString$3((isRecord$2(message.params.turn) ? message.params.turn : {}).id ?? message.params.turnId).trim();
|
|
73724
74510
|
return value.length > 0 ? value : null;
|
|
73725
74511
|
}
|
|
73726
74512
|
function readTurnStatusFromNotification(message) {
|
|
73727
|
-
if (!isRecord$
|
|
74513
|
+
if (!isRecord$2(message.params)) return {
|
|
73728
74514
|
status: null,
|
|
73729
74515
|
reason: null
|
|
73730
74516
|
};
|
|
73731
|
-
const turn = isRecord$
|
|
73732
|
-
const error = isRecord$
|
|
74517
|
+
const turn = isRecord$2(message.params.turn) ? message.params.turn : {};
|
|
74518
|
+
const error = isRecord$2(turn.error) ? turn.error : null;
|
|
73733
74519
|
return {
|
|
73734
74520
|
status: asString$3(turn.status).trim() || null,
|
|
73735
74521
|
reason: error ? asString$3(error.message).trim() || null : null
|
|
73736
74522
|
};
|
|
73737
74523
|
}
|
|
73738
74524
|
function readLegacyEventTurnId(message) {
|
|
73739
|
-
if (!isRecord$
|
|
73740
|
-
const msg = isRecord$
|
|
74525
|
+
if (!isRecord$2(message.params)) return null;
|
|
74526
|
+
const msg = isRecord$2(message.params.msg) ? message.params.msg : {};
|
|
73741
74527
|
const value = asString$3(message.params.id ?? msg.turn_id ?? msg.turnId).trim();
|
|
73742
74528
|
return value.length > 0 ? value : null;
|
|
73743
74529
|
}
|
|
@@ -76259,7 +77045,7 @@ var AccountPoolTurnFailure = class extends Error {
|
|
|
76259
77045
|
this.providerThreadId = input.providerThreadId;
|
|
76260
77046
|
}
|
|
76261
77047
|
};
|
|
76262
|
-
function isRecord$
|
|
77048
|
+
function isRecord$1(value) {
|
|
76263
77049
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
76264
77050
|
}
|
|
76265
77051
|
function asString$2(value) {
|
|
@@ -76393,7 +77179,7 @@ function createDefaultStore() {
|
|
|
76393
77179
|
};
|
|
76394
77180
|
}
|
|
76395
77181
|
function normalizeApiKeyRecord(id, value) {
|
|
76396
|
-
const record = isRecord$
|
|
77182
|
+
const record = isRecord$1(value) ? value : null;
|
|
76397
77183
|
const tokenHash = asString$2(record?.tokenHash);
|
|
76398
77184
|
const tokenPreview = asString$2(record?.tokenPreview);
|
|
76399
77185
|
const createdAt = normalizeIsoString(record?.createdAt);
|
|
@@ -76408,7 +77194,7 @@ function normalizeApiKeyRecord(id, value) {
|
|
|
76408
77194
|
};
|
|
76409
77195
|
}
|
|
76410
77196
|
function normalizeLegacySessionRecord(id, value) {
|
|
76411
|
-
const record = isRecord$
|
|
77197
|
+
const record = isRecord$1(value) ? value : null;
|
|
76412
77198
|
const profileName = asString$2(record?.profileName);
|
|
76413
77199
|
const threadId = asString$2(record?.threadId);
|
|
76414
77200
|
const createdAt = normalizeIsoString(record?.createdAt);
|
|
@@ -76432,19 +77218,19 @@ function normalizeLegacySessionRecord(id, value) {
|
|
|
76432
77218
|
};
|
|
76433
77219
|
}
|
|
76434
77220
|
function normalizeLegacyStore(value) {
|
|
76435
|
-
const record = isRecord$
|
|
77221
|
+
const record = isRecord$1(value) ? value : null;
|
|
76436
77222
|
const apiKeysById = {};
|
|
76437
|
-
for (const [id, keyValue] of Object.entries(isRecord$
|
|
77223
|
+
for (const [id, keyValue] of Object.entries(isRecord$1(record?.apiKeysById) ? record.apiKeysById : {})) {
|
|
76438
77224
|
const normalized = normalizeApiKeyRecord(id, keyValue);
|
|
76439
77225
|
if (normalized) apiKeysById[id] = normalized;
|
|
76440
77226
|
}
|
|
76441
77227
|
const sessionsById = {};
|
|
76442
|
-
for (const [id, sessionValue] of Object.entries(isRecord$
|
|
77228
|
+
for (const [id, sessionValue] of Object.entries(isRecord$1(record?.sessionsById) ? record.sessionsById : {})) {
|
|
76443
77229
|
const normalized = normalizeLegacySessionRecord(id, sessionValue);
|
|
76444
77230
|
if (normalized) sessionsById[id] = normalized;
|
|
76445
77231
|
}
|
|
76446
77232
|
const responseIndex = {};
|
|
76447
|
-
for (const [responseId, sessionId] of Object.entries(isRecord$
|
|
77233
|
+
for (const [responseId, sessionId] of Object.entries(isRecord$1(record?.responseIndex) ? record.responseIndex : {})) {
|
|
76448
77234
|
const normalizedSessionId = asString$2(sessionId);
|
|
76449
77235
|
if (normalizedSessionId) responseIndex[responseId] = normalizedSessionId;
|
|
76450
77236
|
}
|
|
@@ -76457,7 +77243,7 @@ function normalizeLegacyStore(value) {
|
|
|
76457
77243
|
};
|
|
76458
77244
|
}
|
|
76459
77245
|
function normalizeTranscriptEntry(value) {
|
|
76460
|
-
const record = isRecord$
|
|
77246
|
+
const record = isRecord$1(value) ? value : null;
|
|
76461
77247
|
const role = asString$2(record?.role);
|
|
76462
77248
|
const createdAt = normalizeIsoString(record?.createdAt);
|
|
76463
77249
|
if (role !== "user" && role !== "assistant" || !createdAt) return null;
|
|
@@ -76469,7 +77255,7 @@ function normalizeTranscriptEntry(value) {
|
|
|
76469
77255
|
};
|
|
76470
77256
|
}
|
|
76471
77257
|
function normalizeSessionRecord(id, value) {
|
|
76472
|
-
const record = isRecord$
|
|
77258
|
+
const record = isRecord$1(value) ? value : null;
|
|
76473
77259
|
const activeSegmentId = asString$2(record?.activeSegmentId);
|
|
76474
77260
|
const createdAt = normalizeIsoString(record?.createdAt);
|
|
76475
77261
|
const lastUsedAt = normalizeIsoString(record?.lastUsedAt);
|
|
@@ -76502,11 +77288,11 @@ function normalizeSessionRecord(id, value) {
|
|
|
76502
77288
|
responseIds: normalizeStringArray(record?.responseIds).slice(0, MAX_RESPONSE_IDS_PER_SESSION),
|
|
76503
77289
|
rolloverCount: asNumber$1(record?.rolloverCount) ?? 0,
|
|
76504
77290
|
lastRolloverReason: asString$2(record?.lastRolloverReason),
|
|
76505
|
-
transcript: transcript.slice(-
|
|
77291
|
+
transcript: transcript.slice(-64)
|
|
76506
77292
|
};
|
|
76507
77293
|
}
|
|
76508
77294
|
function normalizeSegmentRecord(id, value) {
|
|
76509
|
-
const record = isRecord$
|
|
77295
|
+
const record = isRecord$1(value) ? value : null;
|
|
76510
77296
|
const sessionId = asString$2(record?.sessionId);
|
|
76511
77297
|
const profileName = asString$2(record?.profileName);
|
|
76512
77298
|
const threadId = asString$2(record?.threadId);
|
|
@@ -76527,7 +77313,7 @@ function normalizeSegmentRecord(id, value) {
|
|
|
76527
77313
|
};
|
|
76528
77314
|
}
|
|
76529
77315
|
function normalizeProfileStateRecord(value) {
|
|
76530
|
-
const record = isRecord$
|
|
77316
|
+
const record = isRecord$1(value) ? value : null;
|
|
76531
77317
|
return {
|
|
76532
77318
|
cooldownUntil: normalizeIsoString(record?.cooldownUntil),
|
|
76533
77319
|
lastFailureClass: normalizeFailureClass(record?.lastFailureClass),
|
|
@@ -76536,7 +77322,7 @@ function normalizeProfileStateRecord(value) {
|
|
|
76536
77322
|
};
|
|
76537
77323
|
}
|
|
76538
77324
|
function normalizeResponseIndexRecord(value) {
|
|
76539
|
-
const record = isRecord$
|
|
77325
|
+
const record = isRecord$1(value) ? value : null;
|
|
76540
77326
|
const sessionId = asString$2(record?.sessionId);
|
|
76541
77327
|
const segmentId = asString$2(record?.segmentId);
|
|
76542
77328
|
const createdAt = normalizeIsoString(record?.createdAt) ?? (/* @__PURE__ */ new Date(0)).toISOString();
|
|
@@ -76548,30 +77334,30 @@ function normalizeResponseIndexRecord(value) {
|
|
|
76548
77334
|
};
|
|
76549
77335
|
}
|
|
76550
77336
|
function normalizeStore(value) {
|
|
76551
|
-
const record = isRecord$
|
|
77337
|
+
const record = isRecord$1(value) ? value : null;
|
|
76552
77338
|
const apiKeysById = {};
|
|
76553
|
-
for (const [id, keyValue] of Object.entries(isRecord$
|
|
77339
|
+
for (const [id, keyValue] of Object.entries(isRecord$1(record?.apiKeysById) ? record.apiKeysById : {})) {
|
|
76554
77340
|
const normalized = normalizeApiKeyRecord(id, keyValue);
|
|
76555
77341
|
if (normalized) apiKeysById[id] = normalized;
|
|
76556
77342
|
}
|
|
76557
77343
|
const sessionsById = {};
|
|
76558
|
-
for (const [id, sessionValue] of Object.entries(isRecord$
|
|
77344
|
+
for (const [id, sessionValue] of Object.entries(isRecord$1(record?.sessionsById) ? record.sessionsById : {})) {
|
|
76559
77345
|
const normalized = normalizeSessionRecord(id, sessionValue);
|
|
76560
77346
|
if (normalized) sessionsById[id] = normalized;
|
|
76561
77347
|
}
|
|
76562
77348
|
const segmentsById = {};
|
|
76563
|
-
for (const [id, segmentValue] of Object.entries(isRecord$
|
|
77349
|
+
for (const [id, segmentValue] of Object.entries(isRecord$1(record?.segmentsById) ? record.segmentsById : {})) {
|
|
76564
77350
|
const normalized = normalizeSegmentRecord(id, segmentValue);
|
|
76565
77351
|
if (normalized) segmentsById[id] = normalized;
|
|
76566
77352
|
}
|
|
76567
77353
|
const profilesByName = {};
|
|
76568
|
-
for (const [name, profileValue] of Object.entries(isRecord$
|
|
77354
|
+
for (const [name, profileValue] of Object.entries(isRecord$1(record?.profilesByName) ? record.profilesByName : {})) {
|
|
76569
77355
|
const normalizedName = asString$2(name);
|
|
76570
77356
|
if (!normalizedName) continue;
|
|
76571
77357
|
profilesByName[normalizedName] = normalizeProfileStateRecord(profileValue);
|
|
76572
77358
|
}
|
|
76573
77359
|
const responseIndex = {};
|
|
76574
|
-
for (const [responseId, responseValue] of Object.entries(isRecord$
|
|
77360
|
+
for (const [responseId, responseValue] of Object.entries(isRecord$1(record?.responseIndex) ? record.responseIndex : {})) {
|
|
76575
77361
|
const normalized = normalizeResponseIndexRecord(responseValue);
|
|
76576
77362
|
if (normalized) responseIndex[responseId] = normalized;
|
|
76577
77363
|
}
|
|
@@ -76696,7 +77482,7 @@ function extractTextAndImages(value) {
|
|
|
76696
77482
|
text: value.trim() || null,
|
|
76697
77483
|
images: []
|
|
76698
77484
|
};
|
|
76699
|
-
const record = isRecord$
|
|
77485
|
+
const record = isRecord$1(value) ? value : null;
|
|
76700
77486
|
const arrayValue = Array.isArray(value) ? value : Array.isArray(record?.content) ? record?.content : null;
|
|
76701
77487
|
const directText = asString$2(record?.text) ?? asString$2(record?.content);
|
|
76702
77488
|
const directImage = asString$2(record?.image_url) ?? asString$2(record?.url) ?? asString$2(record?.imageUrl);
|
|
@@ -76711,7 +77497,7 @@ function extractTextAndImages(value) {
|
|
|
76711
77497
|
if (entry.trim().length > 0) texts.push(entry.trim());
|
|
76712
77498
|
continue;
|
|
76713
77499
|
}
|
|
76714
|
-
const part = isRecord$
|
|
77500
|
+
const part = isRecord$1(entry) ? entry : null;
|
|
76715
77501
|
if (!part) continue;
|
|
76716
77502
|
const partType = asString$2(part.type) ?? "text";
|
|
76717
77503
|
const text = asString$2(part.text) ?? asString$2(part.content) ?? asString$2(part.value);
|
|
@@ -76732,7 +77518,7 @@ function assistantLabel(value) {
|
|
|
76732
77518
|
return normalized && normalized.length > 0 ? normalized : null;
|
|
76733
77519
|
}
|
|
76734
77520
|
function isAssistantLikeRecord(value) {
|
|
76735
|
-
const record = isRecord$
|
|
77521
|
+
const record = isRecord$1(value) ? value : null;
|
|
76736
77522
|
if (!record) return false;
|
|
76737
77523
|
return [
|
|
76738
77524
|
assistantLabel(record.role),
|
|
@@ -76745,7 +77531,7 @@ function collectTextFragments(value, depth = 0) {
|
|
|
76745
77531
|
if (depth > 6) return [];
|
|
76746
77532
|
if (typeof value === "string") return value.length > 0 ? [value] : [];
|
|
76747
77533
|
if (Array.isArray(value)) return value.flatMap((entry) => collectTextFragments(entry, depth + 1));
|
|
76748
|
-
const record = isRecord$
|
|
77534
|
+
const record = isRecord$1(value) ? value : null;
|
|
76749
77535
|
if (!record) return [];
|
|
76750
77536
|
return [
|
|
76751
77537
|
asString$2(record.text),
|
|
@@ -76774,7 +77560,7 @@ function extractAssistantTextSnapshot(value, depth = 0) {
|
|
|
76774
77560
|
}
|
|
76775
77561
|
return null;
|
|
76776
77562
|
}
|
|
76777
|
-
const record = isRecord$
|
|
77563
|
+
const record = isRecord$1(value) ? value : null;
|
|
76778
77564
|
if (!record) return null;
|
|
76779
77565
|
const nestedMatch = extractAssistantTextSnapshot(record.turn, depth + 1) ?? extractAssistantTextSnapshot(record.response, depth + 1) ?? extractAssistantTextSnapshot(record.result, depth + 1) ?? extractAssistantTextSnapshot(record.item, depth + 1) ?? extractAssistantTextSnapshot(record.items, depth + 1) ?? extractAssistantTextSnapshot(record.messages, depth + 1) ?? extractAssistantTextSnapshot(record.output, depth + 1) ?? extractAssistantTextSnapshot(record.content, depth + 1);
|
|
76780
77566
|
if (nestedMatch) return nestedMatch;
|
|
@@ -76793,7 +77579,7 @@ function prepareTurnInput(body, fallbackModel) {
|
|
|
76793
77579
|
looseText = [looseText, entry.trim()].filter(Boolean).join("\n\n") || null;
|
|
76794
77580
|
continue;
|
|
76795
77581
|
}
|
|
76796
|
-
const record = isRecord$
|
|
77582
|
+
const record = isRecord$1(entry) ? entry : null;
|
|
76797
77583
|
if (!record) continue;
|
|
76798
77584
|
const entryRole = asString$2(record.role);
|
|
76799
77585
|
const entryType = asString$2(record.type);
|
|
@@ -76810,7 +77596,7 @@ function prepareTurnInput(body, fallbackModel) {
|
|
|
76810
77596
|
if (text) looseText = [looseText, text].filter(Boolean).join("\n\n") || null;
|
|
76811
77597
|
looseImages.push(...images);
|
|
76812
77598
|
}
|
|
76813
|
-
else if (isRecord$
|
|
77599
|
+
else if (isRecord$1(input)) {
|
|
76814
77600
|
const { text, images } = extractTextAndImages(input);
|
|
76815
77601
|
looseText = text;
|
|
76816
77602
|
looseImages.push(...images);
|
|
@@ -76839,7 +77625,7 @@ function prepareTurnInput(body, fallbackModel) {
|
|
|
76839
77625
|
if (transcriptParts.length > 0) promptParts.push(`Conversation so far:\n${transcriptParts.join("\n\n")}`);
|
|
76840
77626
|
if (finalPrompt) promptParts.push(finalPrompt);
|
|
76841
77627
|
const normalizedModel = normalizeModelSlug(asString$2(body.model) ?? fallbackModel, "codex") ?? fallbackModel;
|
|
76842
|
-
const effort = asString$2((isRecord$
|
|
77628
|
+
const effort = asString$2((isRecord$1(body.reasoning) ? body.reasoning : null)?.effort) ?? asString$2(body.effort) ?? void 0;
|
|
76843
77629
|
return {
|
|
76844
77630
|
prompt: promptParts.join("\n\n").trim() || null,
|
|
76845
77631
|
attachments: [...looseImages, ...finalUserImages].map((url) => ({
|
|
@@ -76856,7 +77642,7 @@ function prepareTurnInput(body, fallbackModel) {
|
|
|
76856
77642
|
}
|
|
76857
77643
|
function resolveResponseContinuationKey(body, headers) {
|
|
76858
77644
|
const previousResponseId = asString$2(body.previous_response_id);
|
|
76859
|
-
const conversation = asString$2(body.conversation) ?? (isRecord$
|
|
77645
|
+
const conversation = asString$2(body.conversation) ?? (isRecord$1(body.conversation) ? asString$2(body.conversation.id) : null);
|
|
76860
77646
|
if (conversation && previousResponseId) throw new AccountPoolRequestError({
|
|
76861
77647
|
statusCode: 400,
|
|
76862
77648
|
code: "invalid_request_error",
|
|
@@ -76935,7 +77721,7 @@ async function readJsonRequestBody(req) {
|
|
|
76935
77721
|
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
76936
77722
|
if (!raw) return {};
|
|
76937
77723
|
const parsed = JSON.parse(raw);
|
|
76938
|
-
if (!isRecord$
|
|
77724
|
+
if (!isRecord$1(parsed)) throw new Error("Expected a JSON object request body.");
|
|
76939
77725
|
return parsed;
|
|
76940
77726
|
}
|
|
76941
77727
|
function stringifyFailureReason(failureClass, message) {
|
|
@@ -78112,7 +78898,7 @@ var LocalAccountPool = class LocalAccountPool {
|
|
|
78112
78898
|
images: [],
|
|
78113
78899
|
createdAt: now
|
|
78114
78900
|
});
|
|
78115
|
-
if (session.transcript.length > MAX_TRANSCRIPT_ENTRIES_PER_SESSION) session.transcript = session.transcript.slice(-
|
|
78901
|
+
if (session.transcript.length > MAX_TRANSCRIPT_ENTRIES_PER_SESSION) session.transcript = session.transcript.slice(-64);
|
|
78116
78902
|
segment.lastUsedAt = now;
|
|
78117
78903
|
segment.closedAt = null;
|
|
78118
78904
|
segment.closeReason = null;
|
|
@@ -78317,17 +79103,17 @@ var LocalAccountPool = class LocalAccountPool {
|
|
|
78317
79103
|
if (snapshotText) this.applyObserverTextSnapshot(observer, snapshotText);
|
|
78318
79104
|
}
|
|
78319
79105
|
if (event.method === "turn/completed") {
|
|
78320
|
-
const payload = isRecord$
|
|
78321
|
-
const turn = isRecord$
|
|
79106
|
+
const payload = isRecord$1(event.payload) ? event.payload : null;
|
|
79107
|
+
const turn = isRecord$1(payload?.turn) ? payload?.turn : payload;
|
|
78322
79108
|
const turnStatus = asString$2(turn?.status);
|
|
78323
|
-
const errorMessage = asString$2(isRecord$
|
|
79109
|
+
const errorMessage = asString$2(isRecord$1(turn?.error) ? turn.error.message : void 0) ?? asString$2(payload?.message);
|
|
78324
79110
|
if (turnStatus === "failed" || errorMessage) {
|
|
78325
79111
|
observer.done = true;
|
|
78326
79112
|
observer.reject(new Error(errorMessage ?? "Provider turn failed."));
|
|
78327
79113
|
this.turnObservers.delete(event.threadId);
|
|
78328
79114
|
return;
|
|
78329
79115
|
}
|
|
78330
|
-
const usage = isRecord$
|
|
79116
|
+
const usage = isRecord$1(turn?.usage) ? turn?.usage : void 0;
|
|
78331
79117
|
const snapshotText = observer.text.length > 0 ? null : extractAssistantTextSnapshot(event.payload);
|
|
78332
79118
|
if (snapshotText) this.applyObserverTextSnapshot(observer, snapshotText);
|
|
78333
79119
|
observer.usage = usage;
|
|
@@ -78369,15 +79155,15 @@ var LocalAccountPool = class LocalAccountPool {
|
|
|
78369
79155
|
else observer.pendingDeltas.push(snapshotText);
|
|
78370
79156
|
}
|
|
78371
79157
|
extractEventErrorMessage(payload) {
|
|
78372
|
-
if (!isRecord$
|
|
78373
|
-
return asString$2((isRecord$
|
|
79158
|
+
if (!isRecord$1(payload)) return null;
|
|
79159
|
+
return asString$2((isRecord$1(payload.error) ? payload.error : payload).message) ?? null;
|
|
78374
79160
|
}
|
|
78375
79161
|
readLiveProviderThreadId(threadId) {
|
|
78376
79162
|
const active = this.manager.listSessions().find((session) => session.threadId === ThreadId.makeUnsafe(threadId));
|
|
78377
79163
|
return this.readResumeCursorThreadId(active?.resumeCursor);
|
|
78378
79164
|
}
|
|
78379
79165
|
readResumeCursorThreadId(resumeCursor) {
|
|
78380
|
-
if (!isRecord$
|
|
79166
|
+
if (!isRecord$1(resumeCursor)) return null;
|
|
78381
79167
|
return asString$2(resumeCursor.threadId);
|
|
78382
79168
|
}
|
|
78383
79169
|
async closeLiveSegment(segmentId) {
|
|
@@ -79311,250 +80097,6 @@ async function updateGlobalCliNow() {
|
|
|
79311
80097
|
};
|
|
79312
80098
|
}
|
|
79313
80099
|
//#endregion
|
|
79314
|
-
//#region ../../packages/contracts/src/settings/legacy-localstorage-keys.ts
|
|
79315
|
-
const LEGACY_LOCALSTORAGE_KEYS = [
|
|
79316
|
-
"settings-storage",
|
|
79317
|
-
"provider",
|
|
79318
|
-
"sandbox-storage",
|
|
79319
|
-
"project-settings-storage",
|
|
79320
|
-
"folder-storage",
|
|
79321
|
-
"conversation-categories-storage",
|
|
79322
|
-
"codex:auto-roll-settings"
|
|
79323
|
-
];
|
|
79324
|
-
//#endregion
|
|
79325
|
-
//#region ../../packages/runtime-app-state/src/storage/migrations/v1.ts
|
|
79326
|
-
const SQLITE_STORAGE_DIR = ".f86eb5e712267207";
|
|
79327
|
-
const LEGACY_SETTINGS_FILE = "settings.json";
|
|
79328
|
-
const LEGACY_SETTINGS_BACKUP_FILE = "settings.json.bak";
|
|
79329
|
-
const LEGACY_SYNC_STATE_FILE = "sync-state.json";
|
|
79330
|
-
const LEGACY_APP_SETTINGS_PARITY_FILE = "app-settings-parity.json";
|
|
79331
|
-
const LEGACY_PROFILE_HOMES_DIR = "profile-homes";
|
|
79332
|
-
const LEGACY_SKILLS_DIR = "skills";
|
|
79333
|
-
const LEGACY_SKILLS_REPOS_FILE = "repos.json";
|
|
79334
|
-
const LEGACY_SKILL_MANIFEST = ".codexuse-skill.json";
|
|
79335
|
-
const LEGACY_LICENSE_SECRET_FILE = "license.secret";
|
|
79336
|
-
function isRecord$1(value) {
|
|
79337
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
79338
|
-
}
|
|
79339
|
-
function isMissingPathError(error) {
|
|
79340
|
-
return error.code === "ENOENT";
|
|
79341
|
-
}
|
|
79342
|
-
function resolveHomeDir() {
|
|
79343
|
-
const home = process.env.HOME || process.env.USERPROFILE || nodeOs.homedir();
|
|
79344
|
-
if (!home) throw new Error("HOME is not set.");
|
|
79345
|
-
return home;
|
|
79346
|
-
}
|
|
79347
|
-
function resolveCodexDir() {
|
|
79348
|
-
return nodePath.join(resolveHomeDir(), ".codex");
|
|
79349
|
-
}
|
|
79350
|
-
function resolveLegacyPath(...segments) {
|
|
79351
|
-
return nodePath.join(resolveCodexDir(), ...segments);
|
|
79352
|
-
}
|
|
79353
|
-
function pickAutoRoll(raw) {
|
|
79354
|
-
if (!raw) return null;
|
|
79355
|
-
try {
|
|
79356
|
-
return normalizeAutoRollSettings(raw);
|
|
79357
|
-
} catch {
|
|
79358
|
-
return null;
|
|
79359
|
-
}
|
|
79360
|
-
}
|
|
79361
|
-
function mergeLegacyLocalStoragePatch(payload) {
|
|
79362
|
-
const patch = {};
|
|
79363
|
-
const consumedKeys = /* @__PURE__ */ new Set();
|
|
79364
|
-
const skippedKeys = /* @__PURE__ */ new Set();
|
|
79365
|
-
const legacyPayloadKeys = new Set(Object.keys(payload).filter((key) => LEGACY_LOCALSTORAGE_KEYS.includes(key)));
|
|
79366
|
-
const hasKey = (key) => legacyPayloadKeys.has(key);
|
|
79367
|
-
const markSkippedIfPresent = (key, consumed) => {
|
|
79368
|
-
if (!hasKey(key)) return;
|
|
79369
|
-
if (consumed) consumedKeys.add(key);
|
|
79370
|
-
else skippedKeys.add(key);
|
|
79371
|
-
};
|
|
79372
|
-
const settingsStorage = payload["settings-storage"];
|
|
79373
|
-
if (isRecord$1(settingsStorage)) {
|
|
79374
|
-
const nextExcludeFolders = Array.isArray(settingsStorage.excludeFolders) ? settingsStorage.excludeFolders.filter((item) => typeof item === "string") : void 0;
|
|
79375
|
-
const nextBeep = typeof settingsStorage.enableTaskCompleteBeep === "boolean" ? settingsStorage.enableTaskCompleteBeep : void 0;
|
|
79376
|
-
const nextSleep = typeof settingsStorage.preventSleepDuringTasks === "boolean" ? settingsStorage.preventSleepDuringTasks : void 0;
|
|
79377
|
-
patch.preferences = {
|
|
79378
|
-
excludeFolders: nextExcludeFolders,
|
|
79379
|
-
enableTaskCompleteBeep: nextBeep,
|
|
79380
|
-
preventSleepDuringTasks: nextSleep
|
|
79381
|
-
};
|
|
79382
|
-
markSkippedIfPresent("settings-storage", nextExcludeFolders !== void 0 || nextBeep !== void 0 || nextSleep !== void 0);
|
|
79383
|
-
} else markSkippedIfPresent("settings-storage", false);
|
|
79384
|
-
markSkippedIfPresent("provider", hasKey("provider"));
|
|
79385
|
-
markSkippedIfPresent("sandbox-storage", hasKey("sandbox-storage"));
|
|
79386
|
-
const projectSettings = payload["project-settings-storage"];
|
|
79387
|
-
if (isRecord$1(projectSettings) && isRecord$1(projectSettings.settingsByPath)) {
|
|
79388
|
-
patch.workspaceSettingsByPath = projectSettings.settingsByPath;
|
|
79389
|
-
markSkippedIfPresent("project-settings-storage", true);
|
|
79390
|
-
} else markSkippedIfPresent("project-settings-storage", false);
|
|
79391
|
-
const folder = payload["folder-storage"];
|
|
79392
|
-
if (isRecord$1(folder)) {
|
|
79393
|
-
const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(isRecord$1) : void 0;
|
|
79394
|
-
const pinnedPaths = Array.isArray(folder.pinnedPaths) ? folder.pinnedPaths.filter((item) => typeof item === "string") : void 0;
|
|
79395
|
-
patch.preferences = {
|
|
79396
|
-
...patch.preferences ?? {},
|
|
79397
|
-
folderHistory,
|
|
79398
|
-
pinnedPaths
|
|
79399
|
-
};
|
|
79400
|
-
markSkippedIfPresent("folder-storage", folderHistory !== void 0 || pinnedPaths !== void 0);
|
|
79401
|
-
} else markSkippedIfPresent("folder-storage", false);
|
|
79402
|
-
const categories = payload["conversation-categories-storage"];
|
|
79403
|
-
let consumedCategories = false;
|
|
79404
|
-
if (isRecord$1(categories)) {
|
|
79405
|
-
if (isRecord$1(categories.categoriesByCwd)) {
|
|
79406
|
-
patch.conversationCategoriesByCwd = categories.categoriesByCwd;
|
|
79407
|
-
consumedCategories = true;
|
|
79408
|
-
}
|
|
79409
|
-
if (isRecord$1(categories.conversationCategoryByCwd)) {
|
|
79410
|
-
patch.conversationCategoryAssignmentsByCwd = categories.conversationCategoryByCwd;
|
|
79411
|
-
consumedCategories = true;
|
|
79412
|
-
}
|
|
79413
|
-
}
|
|
79414
|
-
markSkippedIfPresent("conversation-categories-storage", consumedCategories);
|
|
79415
|
-
const legacyAutoRoll = payload["codex:auto-roll-settings"];
|
|
79416
|
-
const autoRoll = pickAutoRoll(legacyAutoRoll);
|
|
79417
|
-
if (autoRoll) {
|
|
79418
|
-
patch.autoRoll = {
|
|
79419
|
-
enabled: autoRoll.enabled,
|
|
79420
|
-
rearmRemainingThreshold: autoRoll.rearmRemainingThreshold,
|
|
79421
|
-
switchRemainingThreshold: autoRoll.switchRemainingThreshold,
|
|
79422
|
-
restartOfficialCodexOnAutoRoll: autoRoll.restartOfficialCodexOnAutoRoll,
|
|
79423
|
-
launchOfficialCodexWhenClosedOnAutoRoll: autoRoll.launchOfficialCodexWhenClosedOnAutoRoll,
|
|
79424
|
-
priorityOrder: autoRoll.priorityOrder,
|
|
79425
|
-
lowRemainingNotificationEnabled: autoRoll.lowRemainingNotificationEnabled,
|
|
79426
|
-
lowRemainingNotificationThreshold: autoRoll.lowRemainingNotificationThreshold
|
|
79427
|
-
};
|
|
79428
|
-
markSkippedIfPresent("codex:auto-roll-settings", true);
|
|
79429
|
-
} else markSkippedIfPresent("codex:auto-roll-settings", false);
|
|
79430
|
-
return {
|
|
79431
|
-
patch,
|
|
79432
|
-
consumedKeys: Array.from(consumedKeys),
|
|
79433
|
-
skippedKeys: Array.from(skippedKeys)
|
|
79434
|
-
};
|
|
79435
|
-
}
|
|
79436
|
-
async function removeIfExists(target) {
|
|
79437
|
-
await promises.rm(target, {
|
|
79438
|
-
recursive: true,
|
|
79439
|
-
force: true
|
|
79440
|
-
});
|
|
79441
|
-
}
|
|
79442
|
-
async function cleanupLegacyCanonicalSources() {
|
|
79443
|
-
const homeDir = resolveHomeDir();
|
|
79444
|
-
await removeIfExists(resolveLegacyAppStatePath());
|
|
79445
|
-
await removeIfExists(nodePath.join(getUserDataDir(), LEGACY_APP_SETTINGS_PARITY_FILE));
|
|
79446
|
-
await removeIfExists(nodePath.join(homeDir, SQLITE_STORAGE_DIR));
|
|
79447
|
-
await removeIfExists(resolveLegacyPath(LEGACY_SETTINGS_FILE));
|
|
79448
|
-
await removeIfExists(resolveLegacyPath(LEGACY_SETTINGS_BACKUP_FILE));
|
|
79449
|
-
await removeIfExists(resolveLegacyPath(LEGACY_SYNC_STATE_FILE));
|
|
79450
|
-
await removeIfExists(resolveLegacyPath(LEGACY_LICENSE_SECRET_FILE));
|
|
79451
|
-
await removeIfExists(resolveLegacyPath(LEGACY_SKILLS_DIR, LEGACY_SKILLS_REPOS_FILE));
|
|
79452
|
-
const profileHomesRoot = resolveLegacyPath(LEGACY_PROFILE_HOMES_DIR);
|
|
79453
|
-
try {
|
|
79454
|
-
const profileHomes = await promises.readdir(profileHomesRoot, { withFileTypes: true });
|
|
79455
|
-
for (const profileHome of profileHomes) {
|
|
79456
|
-
if (!profileHome.isDirectory()) continue;
|
|
79457
|
-
const profileDir = nodePath.join(profileHomesRoot, profileHome.name);
|
|
79458
|
-
let files = [];
|
|
79459
|
-
try {
|
|
79460
|
-
files = await promises.readdir(profileDir);
|
|
79461
|
-
} catch {
|
|
79462
|
-
continue;
|
|
79463
|
-
}
|
|
79464
|
-
for (const file of files) {
|
|
79465
|
-
if (!file.startsWith("profile.json")) continue;
|
|
79466
|
-
await removeIfExists(nodePath.join(profileDir, file));
|
|
79467
|
-
}
|
|
79468
|
-
}
|
|
79469
|
-
} catch (error) {
|
|
79470
|
-
if (!isMissingPathError(error)) logWarn("Failed cleaning legacy profile metadata:", {
|
|
79471
|
-
profileHomesRoot,
|
|
79472
|
-
error: error instanceof Error ? error.message : String(error)
|
|
79473
|
-
});
|
|
79474
|
-
}
|
|
79475
|
-
const skillsRoot = resolveLegacyPath(LEGACY_SKILLS_DIR);
|
|
79476
|
-
try {
|
|
79477
|
-
const skillDirs = await promises.readdir(skillsRoot, { withFileTypes: true });
|
|
79478
|
-
for (const entry of skillDirs) {
|
|
79479
|
-
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
79480
|
-
await removeIfExists(nodePath.join(skillsRoot, entry.name, LEGACY_SKILL_MANIFEST));
|
|
79481
|
-
}
|
|
79482
|
-
} catch (error) {
|
|
79483
|
-
if (!isMissingPathError(error)) logWarn("Failed cleaning legacy skills metadata:", {
|
|
79484
|
-
skillsRoot,
|
|
79485
|
-
error: error instanceof Error ? error.message : String(error)
|
|
79486
|
-
});
|
|
79487
|
-
}
|
|
79488
|
-
}
|
|
79489
|
-
async function importLegacyLocalStorageOnce(payload) {
|
|
79490
|
-
if ((await getAppState()).migration.status === "pending") return {
|
|
79491
|
-
completed: false,
|
|
79492
|
-
importedKeys: [],
|
|
79493
|
-
skippedKeys: []
|
|
79494
|
-
};
|
|
79495
|
-
if (!payload || !isRecord$1(payload)) return {
|
|
79496
|
-
completed: true,
|
|
79497
|
-
importedKeys: [],
|
|
79498
|
-
skippedKeys: []
|
|
79499
|
-
};
|
|
79500
|
-
const { patch, consumedKeys, skippedKeys } = mergeLegacyLocalStoragePatch(payload);
|
|
79501
|
-
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
79502
|
-
if ((await updateAppState((state) => {
|
|
79503
|
-
return {
|
|
79504
|
-
...state,
|
|
79505
|
-
...patch,
|
|
79506
|
-
app: {
|
|
79507
|
-
...state.app,
|
|
79508
|
-
...patch.app ?? {}
|
|
79509
|
-
},
|
|
79510
|
-
autoRoll: {
|
|
79511
|
-
...state.autoRoll,
|
|
79512
|
-
...patch.autoRoll ?? {}
|
|
79513
|
-
},
|
|
79514
|
-
license: {
|
|
79515
|
-
...state.license,
|
|
79516
|
-
...patch.license ?? {}
|
|
79517
|
-
},
|
|
79518
|
-
preferences: {
|
|
79519
|
-
...state.preferences,
|
|
79520
|
-
...patch.preferences ?? {}
|
|
79521
|
-
},
|
|
79522
|
-
workspaceSettingsByPath: {
|
|
79523
|
-
...state.workspaceSettingsByPath,
|
|
79524
|
-
...patch.workspaceSettingsByPath ?? {}
|
|
79525
|
-
},
|
|
79526
|
-
conversationCategoriesByCwd: {
|
|
79527
|
-
...state.conversationCategoriesByCwd,
|
|
79528
|
-
...patch.conversationCategoriesByCwd ?? {}
|
|
79529
|
-
},
|
|
79530
|
-
conversationCategoryAssignmentsByCwd: {
|
|
79531
|
-
...state.conversationCategoryAssignmentsByCwd,
|
|
79532
|
-
...patch.conversationCategoryAssignmentsByCwd ?? {}
|
|
79533
|
-
},
|
|
79534
|
-
migration: {
|
|
79535
|
-
...state.migration,
|
|
79536
|
-
status: "complete",
|
|
79537
|
-
completedAt,
|
|
79538
|
-
localStorageImportedAt: completedAt,
|
|
79539
|
-
lastError: null
|
|
79540
|
-
}
|
|
79541
|
-
};
|
|
79542
|
-
}, {
|
|
79543
|
-
mode: "replace",
|
|
79544
|
-
allowBeforeMigrationComplete: true
|
|
79545
|
-
})).migration.status !== "complete") return {
|
|
79546
|
-
completed: false,
|
|
79547
|
-
importedKeys: [],
|
|
79548
|
-
skippedKeys: []
|
|
79549
|
-
};
|
|
79550
|
-
await cleanupLegacyCanonicalSources();
|
|
79551
|
-
return {
|
|
79552
|
-
completed: true,
|
|
79553
|
-
importedKeys: consumedKeys,
|
|
79554
|
-
skippedKeys
|
|
79555
|
-
};
|
|
79556
|
-
}
|
|
79557
|
-
//#endregion
|
|
79558
80100
|
//#region ../../packages/runtime-integrations/src/agents/service.ts
|
|
79559
80101
|
const AGENTS_FILENAME = "AGENTS.md";
|
|
79560
80102
|
function resolveGlobalPath(options) {
|
|
@@ -79566,7 +80108,7 @@ function getCodexDir(options) {
|
|
|
79566
80108
|
function isPathSafe(normalizedPath, options) {
|
|
79567
80109
|
if (nodePath.basename(normalizedPath) !== AGENTS_FILENAME) return false;
|
|
79568
80110
|
const codexDir = getCodexDir(options);
|
|
79569
|
-
const homeDir = resolveHomeDir
|
|
80111
|
+
const homeDir = resolveHomeDir();
|
|
79570
80112
|
if (normalizedPath === nodePath.join(codexDir, AGENTS_FILENAME)) return true;
|
|
79571
80113
|
const parentDir = nodePath.dirname(normalizedPath);
|
|
79572
80114
|
if (!parentDir.startsWith(homeDir + nodePath.sep) && parentDir !== homeDir) return false;
|
|
@@ -80052,6 +80594,88 @@ async function assertProfileCreationAllowed(profileManager) {
|
|
|
80052
80594
|
if (typeof licenseWithCounts.profileLimit === "number" && licenseWithCounts.profilesRemaining !== null && licenseWithCounts.profilesRemaining <= 0) throw new Error("CodexUse Free supports up to 2 profiles. Upgrade to CodexUse Pro for unlimited profiles.");
|
|
80053
80595
|
}
|
|
80054
80596
|
//#endregion
|
|
80597
|
+
//#region ../../packages/runtime-profiles/src/license/activation.ts
|
|
80598
|
+
const ACTIVATION_SESSION_PARAM = "codexuse_session";
|
|
80599
|
+
const DEFAULT_ACTIVATION_API_URL = "https://api.codexuse.com/v1/activation";
|
|
80600
|
+
const ACTIVATION_REQUEST_TIMEOUT_MS = 1e4;
|
|
80601
|
+
const SESSION_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
80602
|
+
function resolveActivationApiUrl() {
|
|
80603
|
+
return (process.env.CODEXUSE_ACTIVATION_API_URL?.trim() || DEFAULT_ACTIVATION_API_URL).replace(/\/+$/, "");
|
|
80604
|
+
}
|
|
80605
|
+
function isValidSessionId(sessionId) {
|
|
80606
|
+
return SESSION_ID_PATTERN.test(sessionId.trim());
|
|
80607
|
+
}
|
|
80608
|
+
function appendActivationSession(checkoutUrl, sessionId) {
|
|
80609
|
+
const url = new URL(checkoutUrl);
|
|
80610
|
+
url.searchParams.set(ACTIVATION_SESSION_PARAM, sessionId);
|
|
80611
|
+
return url.toString();
|
|
80612
|
+
}
|
|
80613
|
+
async function fetchActivationStatus(sessionId) {
|
|
80614
|
+
if (!isValidSessionId(sessionId)) throw new Error("Invalid activation session.");
|
|
80615
|
+
const controller = new AbortController();
|
|
80616
|
+
const timeout = setTimeout(() => controller.abort(), ACTIVATION_REQUEST_TIMEOUT_MS);
|
|
80617
|
+
try {
|
|
80618
|
+
const url = new URL(resolveActivationApiUrl());
|
|
80619
|
+
url.searchParams.set("session", sessionId);
|
|
80620
|
+
const response = await fetch(url, {
|
|
80621
|
+
method: "GET",
|
|
80622
|
+
signal: controller.signal,
|
|
80623
|
+
headers: { Accept: "application/json" }
|
|
80624
|
+
});
|
|
80625
|
+
if (!response.ok) throw new Error(`Activation check failed (${response.status}).`);
|
|
80626
|
+
const payload = await response.json();
|
|
80627
|
+
if (payload.status !== "pending" && payload.status !== "ready" && payload.status !== "revoked") throw new Error("Activation check returned an invalid status.");
|
|
80628
|
+
return payload;
|
|
80629
|
+
} catch (error) {
|
|
80630
|
+
if (error instanceof Error && error.name === "AbortError") throw new Error("Activation check timed out.");
|
|
80631
|
+
if (error instanceof Error && error.message.toLowerCase().includes("activation check")) throw error;
|
|
80632
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80633
|
+
throw new Error(`Activation check failed: ${message}`);
|
|
80634
|
+
} finally {
|
|
80635
|
+
clearTimeout(timeout);
|
|
80636
|
+
}
|
|
80637
|
+
}
|
|
80638
|
+
function createLicenseActivationSession() {
|
|
80639
|
+
const offer = getActiveOffer();
|
|
80640
|
+
const sessionId = crypto$1.randomUUID();
|
|
80641
|
+
return {
|
|
80642
|
+
sessionId,
|
|
80643
|
+
checkoutUrl: appendActivationSession(buildCheckoutUrl(offer, {
|
|
80644
|
+
directCheckout: true,
|
|
80645
|
+
source: "app",
|
|
80646
|
+
medium: "desktop_checkout",
|
|
80647
|
+
campaign: offer.campaign ?? void 0
|
|
80648
|
+
}), sessionId)
|
|
80649
|
+
};
|
|
80650
|
+
}
|
|
80651
|
+
async function pollLicenseActivation(sessionId) {
|
|
80652
|
+
const current = await licenseService.getCachedStatus();
|
|
80653
|
+
if (current.isPro) return {
|
|
80654
|
+
status: "activated",
|
|
80655
|
+
license: current,
|
|
80656
|
+
message: "Pro is already active."
|
|
80657
|
+
};
|
|
80658
|
+
const payload = await fetchActivationStatus(sessionId);
|
|
80659
|
+
if (payload.status === "pending") return {
|
|
80660
|
+
status: "pending",
|
|
80661
|
+
message: "Waiting for Gumroad confirmation."
|
|
80662
|
+
};
|
|
80663
|
+
if (payload.status === "revoked") return {
|
|
80664
|
+
status: "revoked",
|
|
80665
|
+
message: "This purchase was refunded or disputed."
|
|
80666
|
+
};
|
|
80667
|
+
const licenseKey = payload.licenseKey?.trim();
|
|
80668
|
+
if (!licenseKey) return {
|
|
80669
|
+
status: "pending",
|
|
80670
|
+
message: "Waiting for Gumroad to attach the license key."
|
|
80671
|
+
};
|
|
80672
|
+
return {
|
|
80673
|
+
status: "activated",
|
|
80674
|
+
license: await licenseService.activate(licenseKey),
|
|
80675
|
+
message: "Pro unlocked automatically after purchase."
|
|
80676
|
+
};
|
|
80677
|
+
}
|
|
80678
|
+
//#endregion
|
|
80055
80679
|
//#region src/codex/runtimeInspection.ts
|
|
80056
80680
|
const COMMAND_TIMEOUT_MS$1 = 5e3;
|
|
80057
80681
|
const AUTH_STATUS_TIMEOUT_MS = 8e3;
|
|
@@ -82600,7 +83224,6 @@ const LAUNCH_WAIT_MS = 15e3;
|
|
|
82600
83224
|
const POLL_INTERVAL_MS = 250;
|
|
82601
83225
|
const APP_DISCOVERY_CACHE_TTL_MS = 6e4;
|
|
82602
83226
|
const APP_DISCOVERY_MISS_CACHE_TTL_MS = 5e3;
|
|
82603
|
-
const OFFICIAL_CODEX_ACTIVITY_LIMIT = 50;
|
|
82604
83227
|
let profileActionLock = Promise.resolve();
|
|
82605
83228
|
let appDiscoveryCache = null;
|
|
82606
83229
|
function logOfficialCodexRestart(level, message, context) {
|
|
@@ -82642,7 +83265,7 @@ async function recordOfficialCodexActivity(input) {
|
|
|
82642
83265
|
observedProfileMatchSource: input.observedProfileMatchSource ?? null
|
|
82643
83266
|
};
|
|
82644
83267
|
try {
|
|
82645
|
-
await updateAppState((state) => ({ officialCodex: { activity: [...state.officialCodex.activity, entry].slice(-
|
|
83268
|
+
await updateAppState((state) => ({ officialCodex: { activity: [...state.officialCodex.activity, entry].slice(-50) } }));
|
|
82646
83269
|
} catch (error) {
|
|
82647
83270
|
logOfficialCodexRestart("warn", "Failed to record official Codex activity.", {
|
|
82648
83271
|
kind: entry.kind,
|
|
@@ -83705,6 +84328,38 @@ var ServerLifecycleError = class extends TaggedErrorClass()("ServerLifecycleErro
|
|
|
83705
84328
|
operation: String$1,
|
|
83706
84329
|
cause: optional$2(Defect)
|
|
83707
84330
|
}) {};
|
|
84331
|
+
const BOOTSTRAP_WS_TIMEOUT_MS = 15e3;
|
|
84332
|
+
const BOOTSTRAP_FAULTS_ENABLED = process.env.CODEXUSE_ENABLE_BOOTSTRAP_FAULTS === "1";
|
|
84333
|
+
const BOOTSTRAP_FAULT = BOOTSTRAP_FAULTS_ENABLED ? process.env.CODEXUSE_BOOTSTRAP_FAULT?.trim() ?? "" : "";
|
|
84334
|
+
function waitForever() {
|
|
84335
|
+
return new Promise(() => {});
|
|
84336
|
+
}
|
|
84337
|
+
function withPromiseTimeout(promise, timeoutMs, message) {
|
|
84338
|
+
return new Promise((resolve, reject) => {
|
|
84339
|
+
const timeout = setTimeout(() => reject(new Error(message)), timeoutMs);
|
|
84340
|
+
timeout.unref?.();
|
|
84341
|
+
promise.then((value) => {
|
|
84342
|
+
clearTimeout(timeout);
|
|
84343
|
+
resolve(value);
|
|
84344
|
+
}, (error) => {
|
|
84345
|
+
clearTimeout(timeout);
|
|
84346
|
+
reject(error);
|
|
84347
|
+
});
|
|
84348
|
+
});
|
|
84349
|
+
}
|
|
84350
|
+
async function runBootstrapWsTask(operation, task) {
|
|
84351
|
+
return withPromiseTimeout((async () => {
|
|
84352
|
+
if (BOOTSTRAP_FAULTS_ENABLED && operation === WS_METHODS.appStateGet) {
|
|
84353
|
+
if (BOOTSTRAP_FAULT === "rpc-hang" || BOOTSTRAP_FAULT === "storage-deadlock") await waitForever();
|
|
84354
|
+
if (BOOTSTRAP_FAULT === "sqlite-lock") {
|
|
84355
|
+
const error = /* @__PURE__ */ new Error("database is locked");
|
|
84356
|
+
error.code = "SQLITE_BUSY";
|
|
84357
|
+
throw error;
|
|
84358
|
+
}
|
|
84359
|
+
}
|
|
84360
|
+
return task();
|
|
84361
|
+
})(), BOOTSTRAP_WS_TIMEOUT_MS, `Bootstrap WS ${operation} timed out after ${BOOTSTRAP_WS_TIMEOUT_MS}ms.`);
|
|
84362
|
+
}
|
|
83708
84363
|
const createServer = fn(function* () {
|
|
83709
84364
|
const serverConfig = yield* ServerConfig$1;
|
|
83710
84365
|
const { port, cwd, staticDir, devUrl, authToken, host, logWebSocketEvents, autoBootstrapProjectFromCwd } = serverConfig;
|
|
@@ -85761,7 +86416,7 @@ const createServer = fn(function* () {
|
|
|
85761
86416
|
issues: []
|
|
85762
86417
|
};
|
|
85763
86418
|
}
|
|
85764
|
-
case WS_METHODS.appStateGet: return yield* promise(() => getAppState());
|
|
86419
|
+
case WS_METHODS.appStateGet: return yield* promise(() => runBootstrapWsTask(WS_METHODS.appStateGet, () => getAppState()));
|
|
85765
86420
|
case WS_METHODS.appStatePatch: {
|
|
85766
86421
|
const body = stripRequestTag(request.body);
|
|
85767
86422
|
if (!body.patch || typeof body.patch !== "object" || Array.isArray(body.patch)) return yield* new RouteRequestError({ message: "App state patch must be an object." });
|
|
@@ -86133,6 +86788,11 @@ const createServer = fn(function* () {
|
|
|
86133
86788
|
throw error;
|
|
86134
86789
|
}
|
|
86135
86790
|
}
|
|
86791
|
+
case WS_METHODS.licenseActivationCreate: return createLicenseActivationSession();
|
|
86792
|
+
case WS_METHODS.licenseActivationPoll: {
|
|
86793
|
+
const body = stripRequestTag(request.body);
|
|
86794
|
+
return yield* promise(() => pollLicenseActivation(body.sessionId));
|
|
86795
|
+
}
|
|
86136
86796
|
case WS_METHODS.syncStatus: return yield* promise(() => getCloudSyncStatus());
|
|
86137
86797
|
case WS_METHODS.syncPull: {
|
|
86138
86798
|
const result = yield* promise(() => pullCloudSync());
|
|
@@ -86616,6 +87276,9 @@ const reconcileDuplicateProjects = gen(function* () {
|
|
|
86616
87276
|
* @module CliConfig
|
|
86617
87277
|
*/
|
|
86618
87278
|
var StartupError = class extends TaggedError("StartupError") {};
|
|
87279
|
+
const DESKTOP_APP_STATE_INIT_TIMEOUT_MS = 15e3;
|
|
87280
|
+
const DESKTOP_STORAGE_MIGRATION_TIMEOUT_MS = 15e3;
|
|
87281
|
+
const DESKTOP_PROJECTS_STATE_DIRNAME = "t3-projects";
|
|
86619
87282
|
/**
|
|
86620
87283
|
* CliConfig - Service tag for startup CLI/runtime helpers.
|
|
86621
87284
|
*/
|
|
@@ -86691,6 +87354,24 @@ const ServerConfigLive = (input) => effect(ServerConfig$1, gen(function* () {
|
|
|
86691
87354
|
const LayerLive = (input) => empty$7.pipe(provideMerge(makeServerRuntimeServicesLayer()), provideMerge(makeServerProviderLayer()), provideMerge(ProviderHealthLive), provideMerge(ProjectionProjectRepositoryLive), provideMerge(ProjectionThreadRepositoryLive), provideMerge(ProjectionThreadMessageRepositoryLive), provideMerge(ProjectionThreadProposedPlanRepositoryLive), provideMerge(ProjectionThreadActivityRepositoryLive), provideMerge(ProjectionThreadSessionRepositoryLive), provideMerge(ProjectionTurnRepositoryLive), provideMerge(ProjectionCheckpointRepositoryLive), provideMerge(ProjectionStateRepositoryLive), provideMerge(ProviderSessionRuntimeRepositoryLive), provideMerge(layerConfig), provideMerge(ServerLoggerLive), provideMerge(ServerConfigLive(input)));
|
|
86692
87355
|
const isWildcardHost = (host) => host === "0.0.0.0" || host === "::" || host === "[::]";
|
|
86693
87356
|
const formatHostForUrl = (host) => host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
|
|
87357
|
+
function withStartupTimeout(promise, timeoutMs, message) {
|
|
87358
|
+
return new Promise((resolve, reject) => {
|
|
87359
|
+
const timeout = setTimeout(() => reject(new Error(message)), timeoutMs);
|
|
87360
|
+
timeout.unref?.();
|
|
87361
|
+
promise.then((value) => {
|
|
87362
|
+
clearTimeout(timeout);
|
|
87363
|
+
resolve(value);
|
|
87364
|
+
}, (error) => {
|
|
87365
|
+
clearTimeout(timeout);
|
|
87366
|
+
reject(error);
|
|
87367
|
+
});
|
|
87368
|
+
});
|
|
87369
|
+
}
|
|
87370
|
+
function resolveDesktopAppUserDataDir(stateDir) {
|
|
87371
|
+
const normalized = nodePath.normalize(stateDir);
|
|
87372
|
+
if (nodePath.basename(normalized) === DESKTOP_PROJECTS_STATE_DIRNAME) return nodePath.dirname(normalized);
|
|
87373
|
+
return normalized;
|
|
87374
|
+
}
|
|
86694
87375
|
function sendDesktopParentMessage(payload) {
|
|
86695
87376
|
if (typeof process.send !== "function") return;
|
|
86696
87377
|
try {
|
|
@@ -86744,6 +87425,29 @@ const makeServerProgram = (input) => gen(function* () {
|
|
|
86744
87425
|
const config = yield* ServerConfig$1;
|
|
86745
87426
|
if (!config.devUrl && !config.staticDir) yield* logWarning$1("web bundle missing and no VITE_DEV_SERVER_URL; web UI unavailable", { hint: "Run `bun run --cwd apps/web build` or set VITE_DEV_SERVER_URL for dev mode." });
|
|
86746
87427
|
yield* start;
|
|
87428
|
+
if (config.mode === "desktop") {
|
|
87429
|
+
const appUserDataDir = resolveDesktopAppUserDataDir(config.stateDir);
|
|
87430
|
+
yield* tryPromise({
|
|
87431
|
+
try: () => withStartupTimeout(initializeAppState(appUserDataDir), DESKTOP_APP_STATE_INIT_TIMEOUT_MS, `Desktop app-state initialization timed out after ${DESKTOP_APP_STATE_INIT_TIMEOUT_MS}ms.`),
|
|
87432
|
+
catch: (cause) => new StartupError({
|
|
87433
|
+
message: "Failed to initialize desktop app state",
|
|
87434
|
+
cause
|
|
87435
|
+
})
|
|
87436
|
+
}).pipe(tap(() => logInfo$1("Desktop app state initialized", { appUserDataDir })), catch_((cause) => logWarning$1("desktop app-state init skipped", {
|
|
87437
|
+
cause,
|
|
87438
|
+
appUserDataDir
|
|
87439
|
+
})));
|
|
87440
|
+
yield* tryPromise({
|
|
87441
|
+
try: () => withStartupTimeout(runStorageMigrationV1(), DESKTOP_STORAGE_MIGRATION_TIMEOUT_MS, `Desktop storage migration timed out after ${DESKTOP_STORAGE_MIGRATION_TIMEOUT_MS}ms.`),
|
|
87442
|
+
catch: (cause) => new StartupError({
|
|
87443
|
+
message: "Failed to run desktop storage migration",
|
|
87444
|
+
cause
|
|
87445
|
+
})
|
|
87446
|
+
}).pipe(tap(() => logInfo$1("Desktop storage migration finished", { appUserDataDir })), catch_((cause) => logWarning$1("desktop storage migration skipped", {
|
|
87447
|
+
cause,
|
|
87448
|
+
appUserDataDir
|
|
87449
|
+
})));
|
|
87450
|
+
}
|
|
86747
87451
|
yield* sync(() => {
|
|
86748
87452
|
const elapsedMs = Date.now() - startupStartedAt;
|
|
86749
87453
|
sendDesktopParentMessage({
|