codexuse-cli 3.9.8 → 3.9.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2624,7 +2624,7 @@ function normalizeAppState(raw) {
2624
2624
  merged.officialCodex.activity = Array.isArray(merged.officialCodex.activity) ? merged.officialCodex.activity.filter((entry) => isRecord2(entry)).map((entry) => ({
2625
2625
  id: asString(entry.id) ?? "",
2626
2626
  at: asString(entry.at) ?? (/* @__PURE__ */ new Date(0)).toISOString(),
2627
- kind: entry.kind === "auto-roll-eval" || entry.kind === "profile-switch" || entry.kind === "auth-verified" || entry.kind === "official-codex-restart" || entry.kind === "low-remaining-alert" ? entry.kind : "auto-roll-eval",
2627
+ kind: entry.kind === "auto-roll-eval" || entry.kind === "profile-switch" || entry.kind === "auth-verified" || entry.kind === "official-codex-restart" || entry.kind === "reset-window-activation" || entry.kind === "low-remaining-alert" ? entry.kind : "auto-roll-eval",
2628
2628
  status: asString(entry.status) ?? "unknown",
2629
2629
  reason: asString(entry.reason),
2630
2630
  decisionId: asString(entry.decisionId),
@@ -2643,7 +2643,9 @@ function normalizeAppState(raw) {
2643
2643
  restartResult: asString(entry.restartResult),
2644
2644
  observedProfileName: asString(entry.observedProfileName),
2645
2645
  observedProfileKeyHash: asString(entry.observedProfileKeyHash),
2646
- observedProfileMatchSource: asString(entry.observedProfileMatchSource)
2646
+ observedProfileMatchSource: asString(
2647
+ entry.observedProfileMatchSource
2648
+ )
2647
2649
  })).filter((entry) => entry.id && entry.at).slice(-50) : [];
2648
2650
  if (!isRecord2(merged.officialCodex.instancesByProfileName)) {
2649
2651
  merged.officialCodex.instancesByProfileName = {};
@@ -2767,7 +2769,9 @@ function normalizeAppState(raw) {
2767
2769
  merged.ui.profiles.groupBy = asString(merged.ui.profiles.groupBy);
2768
2770
  merged.ui.profiles.planFilter = asString(merged.ui.profiles.planFilter);
2769
2771
  merged.ui.profiles.healthFilter = asString(merged.ui.profiles.healthFilter);
2770
- merged.ui.profiles.customGroupFilter = asString(merged.ui.profiles.customGroupFilter);
2772
+ merged.ui.profiles.customGroupFilter = asString(
2773
+ merged.ui.profiles.customGroupFilter
2774
+ );
2771
2775
  if (typeof merged.ui.profiles.toolbarOpen !== "boolean") {
2772
2776
  merged.ui.profiles.toolbarOpen = null;
2773
2777
  }
@@ -2775,13 +2779,15 @@ function normalizeAppState(raw) {
2775
2779
  merged.ui.profiles.collapsedSections = {};
2776
2780
  } else {
2777
2781
  merged.ui.profiles.collapsedSections = Object.fromEntries(
2778
- Object.entries(merged.ui.profiles.collapsedSections).flatMap(([key, value]) => {
2779
- const normalizedKey = asString(key);
2780
- if (!normalizedKey || typeof value !== "boolean") {
2781
- return [];
2782
+ Object.entries(merged.ui.profiles.collapsedSections).flatMap(
2783
+ ([key, value]) => {
2784
+ const normalizedKey = asString(key);
2785
+ if (!normalizedKey || typeof value !== "boolean") {
2786
+ return [];
2787
+ }
2788
+ return [[normalizedKey, value]];
2782
2789
  }
2783
- return [[normalizedKey, value]];
2784
- })
2790
+ )
2785
2791
  );
2786
2792
  }
2787
2793
  if (!isRecord2(merged.ui.onboarding)) {
@@ -2810,26 +2816,30 @@ function normalizeAppState(raw) {
2810
2816
  merged.ui.onboarding.nudgeCooldowns = {};
2811
2817
  } else {
2812
2818
  merged.ui.onboarding.nudgeCooldowns = Object.fromEntries(
2813
- Object.entries(merged.ui.onboarding.nudgeCooldowns).flatMap(([key, value]) => {
2814
- const normalizedKey = asString(key);
2815
- if (!normalizedKey || !Number.isFinite(value)) {
2816
- return [];
2819
+ Object.entries(merged.ui.onboarding.nudgeCooldowns).flatMap(
2820
+ ([key, value]) => {
2821
+ const normalizedKey = asString(key);
2822
+ if (!normalizedKey || !Number.isFinite(value)) {
2823
+ return [];
2824
+ }
2825
+ return [[normalizedKey, Number(value)]];
2817
2826
  }
2818
- return [[normalizedKey, Number(value)]];
2819
- })
2827
+ )
2820
2828
  );
2821
2829
  }
2822
2830
  if (!isRecord2(merged.ui.onboarding.nudgeDismissCount)) {
2823
2831
  merged.ui.onboarding.nudgeDismissCount = {};
2824
2832
  } else {
2825
2833
  merged.ui.onboarding.nudgeDismissCount = Object.fromEntries(
2826
- Object.entries(merged.ui.onboarding.nudgeDismissCount).flatMap(([key, value]) => {
2827
- const normalizedKey = asString(key);
2828
- if (!normalizedKey || !Number.isFinite(value)) {
2829
- return [];
2834
+ Object.entries(merged.ui.onboarding.nudgeDismissCount).flatMap(
2835
+ ([key, value]) => {
2836
+ const normalizedKey = asString(key);
2837
+ if (!normalizedKey || !Number.isFinite(value)) {
2838
+ return [];
2839
+ }
2840
+ return [[normalizedKey, Number(value)]];
2830
2841
  }
2831
- return [[normalizedKey, Number(value)]];
2832
- })
2842
+ )
2833
2843
  );
2834
2844
  }
2835
2845
  if (typeof merged.ui.onboarding.proUnlockedCelebrated !== "boolean") {
@@ -2839,17 +2849,21 @@ function normalizeAppState(raw) {
2839
2849
  merged.ui.projectThreadSelections = {};
2840
2850
  } else {
2841
2851
  merged.ui.projectThreadSelections = Object.fromEntries(
2842
- Object.entries(merged.ui.projectThreadSelections).flatMap(([projectId, threadId]) => {
2843
- const normalizedProjectId = asString(projectId);
2844
- if (!normalizedProjectId) {
2845
- return [];
2852
+ Object.entries(merged.ui.projectThreadSelections).flatMap(
2853
+ ([projectId, threadId]) => {
2854
+ const normalizedProjectId = asString(projectId);
2855
+ if (!normalizedProjectId) {
2856
+ return [];
2857
+ }
2858
+ const normalizedThreadId = typeof threadId === "string" && threadId.trim().length > 0 ? threadId.trim() : null;
2859
+ return [[normalizedProjectId, normalizedThreadId]];
2846
2860
  }
2847
- const normalizedThreadId = typeof threadId === "string" && threadId.trim().length > 0 ? threadId.trim() : null;
2848
- return [[normalizedProjectId, normalizedThreadId]];
2849
- })
2861
+ )
2850
2862
  );
2851
2863
  }
2852
- merged.ui.duplicateWarningDismissedKey = asString(merged.ui.duplicateWarningDismissedKey);
2864
+ merged.ui.duplicateWarningDismissedKey = asString(
2865
+ merged.ui.duplicateWarningDismissedKey
2866
+ );
2853
2867
  if (typeof merged.ui.pendingLicenseActivation !== "boolean") {
2854
2868
  merged.ui.pendingLicenseActivation = false;
2855
2869
  }
@@ -2868,14 +2882,16 @@ function normalizeAppState(raw) {
2868
2882
  merged.profileDashboard.customGroupsByAccountKey = {};
2869
2883
  } else {
2870
2884
  merged.profileDashboard.customGroupsByAccountKey = Object.fromEntries(
2871
- Object.entries(merged.profileDashboard.customGroupsByAccountKey).flatMap(([key, value]) => {
2872
- const normalizedKey = asString(key);
2873
- const normalizedValue = asString(value);
2874
- if (!normalizedKey || !normalizedValue) {
2875
- return [];
2885
+ Object.entries(merged.profileDashboard.customGroupsByAccountKey).flatMap(
2886
+ ([key, value]) => {
2887
+ const normalizedKey = asString(key);
2888
+ const normalizedValue = asString(value);
2889
+ if (!normalizedKey || !normalizedValue) {
2890
+ return [];
2891
+ }
2892
+ return [[normalizedKey, normalizedValue]];
2876
2893
  }
2877
- return [[normalizedKey, normalizedValue]];
2878
- })
2894
+ )
2879
2895
  );
2880
2896
  }
2881
2897
  {
@@ -2942,7 +2958,9 @@ function normalizeAppState(raw) {
2942
2958
  }
2943
2959
  merged.analytics.anonymousId = asString(merged.analytics.anonymousId);
2944
2960
  if (!merged.analytics.anonymousId) {
2945
- const legacyInstallId = asString(merged.telemetry?.installId);
2961
+ const legacyInstallId = asString(
2962
+ merged.telemetry?.installId
2963
+ );
2946
2964
  merged.analytics.anonymousId = legacyInstallId;
2947
2965
  }
2948
2966
  if (typeof merged.analytics.enabled !== "boolean") {
@@ -3013,10 +3031,18 @@ async function readLegacyAppStateFromDisk() {
3013
3031
  }
3014
3032
  }
3015
3033
  async function readAppStateFromStorage() {
3016
- return readDocument(resolveStorageDbPath(), APP_STATE_DOCUMENT, normalizeAppState);
3034
+ return readDocument(
3035
+ resolveStorageDbPath(),
3036
+ APP_STATE_DOCUMENT,
3037
+ normalizeAppState
3038
+ );
3017
3039
  }
3018
3040
  async function writeAppStateToStorage(state) {
3019
- return writeDocument(resolveStorageDbPath(), APP_STATE_DOCUMENT, normalizeAppState(state));
3041
+ return writeDocument(
3042
+ resolveStorageDbPath(),
3043
+ APP_STATE_DOCUMENT,
3044
+ normalizeAppState(state)
3045
+ );
3020
3046
  }
3021
3047
  async function ensureInitialized() {
3022
3048
  if (appStateCache) {
@@ -4037,8 +4063,125 @@ function logInfo(...args) {
4037
4063
 
4038
4064
  // ../../packages/runtime-codex/src/codex/rpc.ts
4039
4065
  var RPC_TIMEOUT_MS = 1e4;
4066
+ var ACTIVATION_TURN_TIMEOUT_MS = 9e4;
4067
+ var ACTIVATION_PROMPT = "Reply with exactly: ok.";
4068
+ var ACTIVATION_MODEL = "gpt-5.1-codex-mini";
4040
4069
  var MAX_STDERR_CAPTURE_CHARS = 32768;
4041
4070
  var REFRESH_TOKEN_REDEEMED_SNIPPET = "refresh token was already used";
4071
+ function isRecord4(value) {
4072
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
4073
+ }
4074
+ function asString3(value) {
4075
+ return typeof value === "string" ? value : value != null ? String(value) : "";
4076
+ }
4077
+ function createRpcMessageReader(rl) {
4078
+ const queue = [];
4079
+ const waiters = [];
4080
+ let closedError = null;
4081
+ const rejectAll = (error) => {
4082
+ closedError = error;
4083
+ while (waiters.length > 0) {
4084
+ const waiter = waiters.shift();
4085
+ clearTimeout(waiter.timer);
4086
+ waiter.reject(error);
4087
+ }
4088
+ };
4089
+ const onLine = (line) => {
4090
+ let parsed;
4091
+ try {
4092
+ parsed = JSON.parse(line);
4093
+ } catch {
4094
+ rejectAll(new Error("codex RPC returned malformed JSON"));
4095
+ return;
4096
+ }
4097
+ const waiterIndex = waiters.findIndex((waiter) => waiter.predicate(parsed));
4098
+ if (waiterIndex >= 0) {
4099
+ const [waiter] = waiters.splice(waiterIndex, 1);
4100
+ clearTimeout(waiter.timer);
4101
+ waiter.resolve(parsed);
4102
+ return;
4103
+ }
4104
+ queue.push(parsed);
4105
+ };
4106
+ const onClose = () => {
4107
+ rejectAll(new Error("codex RPC stream closed before response"));
4108
+ };
4109
+ rl.on("line", onLine);
4110
+ rl.on("close", onClose);
4111
+ return {
4112
+ read(predicate, timeoutMs) {
4113
+ const queuedIndex = queue.findIndex(predicate);
4114
+ if (queuedIndex >= 0) {
4115
+ const [message] = queue.splice(queuedIndex, 1);
4116
+ return Promise.resolve(message);
4117
+ }
4118
+ if (closedError) {
4119
+ return Promise.reject(closedError);
4120
+ }
4121
+ return new Promise((resolve, reject) => {
4122
+ const waiter = {
4123
+ predicate,
4124
+ resolve,
4125
+ reject,
4126
+ timer: setTimeout(
4127
+ () => {
4128
+ const index = waiters.indexOf(waiter);
4129
+ if (index >= 0) {
4130
+ waiters.splice(index, 1);
4131
+ }
4132
+ reject(new Error("codex RPC timed out"));
4133
+ },
4134
+ Math.max(1, timeoutMs)
4135
+ )
4136
+ };
4137
+ waiters.push(waiter);
4138
+ });
4139
+ },
4140
+ dispose() {
4141
+ rl.off("line", onLine);
4142
+ rl.off("close", onClose);
4143
+ while (waiters.length > 0) {
4144
+ const waiter = waiters.shift();
4145
+ clearTimeout(waiter.timer);
4146
+ }
4147
+ }
4148
+ };
4149
+ }
4150
+ function readThreadIdFromResult(result) {
4151
+ if (!isRecord4(result)) return null;
4152
+ const thread = isRecord4(result.thread) ? result.thread : {};
4153
+ const value = asString3(thread.id ?? result.threadId).trim();
4154
+ return value.length > 0 ? value : null;
4155
+ }
4156
+ function readTurnIdFromResult(result) {
4157
+ if (!isRecord4(result)) return null;
4158
+ const turn = isRecord4(result.turn) ? result.turn : {};
4159
+ const value = asString3(turn.id ?? result.turnId).trim();
4160
+ return value.length > 0 ? value : null;
4161
+ }
4162
+ function readTurnIdFromNotification(message) {
4163
+ if (!isRecord4(message.params)) return null;
4164
+ const turn = isRecord4(message.params.turn) ? message.params.turn : {};
4165
+ const value = asString3(turn.id ?? message.params.turnId).trim();
4166
+ return value.length > 0 ? value : null;
4167
+ }
4168
+ function readTurnStatusFromNotification(message) {
4169
+ if (!isRecord4(message.params)) {
4170
+ return { status: null, reason: null };
4171
+ }
4172
+ const turn = isRecord4(message.params.turn) ? message.params.turn : {};
4173
+ const error = isRecord4(turn.error) ? turn.error : null;
4174
+ return {
4175
+ status: asString3(turn.status).trim() || null,
4176
+ reason: error ? asString3(error.message).trim() || null : null
4177
+ };
4178
+ }
4179
+ function readLegacyEventTurnId(message) {
4180
+ if (!isRecord4(message.params)) return null;
4181
+ const msg = isRecord4(message.params.msg) ? message.params.msg : {};
4182
+ const value = asString3(message.params.id ?? msg.turn_id ?? msg.turnId).trim();
4183
+ return value.length > 0 ? value : null;
4184
+ }
4042
4185
  function parseTimestamp2(value) {
4043
4186
  if (typeof value !== "string" || value.trim().length === 0) {
4044
4187
  return null;
@@ -4089,8 +4232,17 @@ function extractAuthRecencyMs(content) {
4089
4232
  const rootLastRefresh = parseTimestamp2(parsed.last_refresh);
4090
4233
  const nestedLastRefresh = parseTimestamp2(parsed.tokens?.last_refresh);
4091
4234
  const rootAccessIssuedAt = extractJwtIssuedAtMs(parsed.access_token);
4092
- const nestedAccessIssuedAt = extractJwtIssuedAtMs(parsed.tokens?.access_token);
4093
- const candidates = [rootLastRefresh, nestedLastRefresh, rootAccessIssuedAt, nestedAccessIssuedAt].filter((value) => typeof value === "number" && Number.isFinite(value));
4235
+ const nestedAccessIssuedAt = extractJwtIssuedAtMs(
4236
+ parsed.tokens?.access_token
4237
+ );
4238
+ const candidates = [
4239
+ rootLastRefresh,
4240
+ nestedLastRefresh,
4241
+ rootAccessIssuedAt,
4242
+ nestedAccessIssuedAt
4243
+ ].filter(
4244
+ (value) => typeof value === "number" && Number.isFinite(value)
4245
+ );
4094
4246
  if (candidates.length === 0) {
4095
4247
  return null;
4096
4248
  }
@@ -4141,10 +4293,13 @@ function isRpcResponseForRequest(message, requestId) {
4141
4293
  }
4142
4294
  async function readRpcResponseById(rl, requestId, timeoutMs) {
4143
4295
  return new Promise((resolve, reject) => {
4144
- const timer = setTimeout(() => {
4145
- cleanup();
4146
- reject(new Error("codex RPC timed out"));
4147
- }, Math.max(1, timeoutMs));
4296
+ const timer = setTimeout(
4297
+ () => {
4298
+ cleanup();
4299
+ reject(new Error("codex RPC timed out"));
4300
+ },
4301
+ Math.max(1, timeoutMs)
4302
+ );
4148
4303
  const cleanup = () => {
4149
4304
  clearTimeout(timer);
4150
4305
  rl.off("line", onLine);
@@ -4294,7 +4449,11 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
4294
4449
  throw new Error(formatRpcError("initialize", initializeResponse.error));
4295
4450
  }
4296
4451
  await sendPayload(child, { method: "initialized", params: {} });
4297
- await sendPayload(child, { id: 2, method: "account/rateLimits/read", params: {} });
4452
+ await sendPayload(child, {
4453
+ id: 2,
4454
+ method: "account/rateLimits/read",
4455
+ params: {}
4456
+ });
4298
4457
  const message = await readRpcResponseById(rl, 2, RPC_TIMEOUT_MS);
4299
4458
  if (message.error) {
4300
4459
  const base = formatRpcError("account/rateLimits/read", message.error);
@@ -4315,11 +4474,181 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
4315
4474
  if (shouldWriteBackAuth(initialSourceAuth, currentSourceAuth, updatedAuth)) {
4316
4475
  await import_node_fs5.promises.writeFile(sourceAuthPath, updatedAuth, "utf8");
4317
4476
  } else if (currentSourceAuth && currentSourceAuth !== updatedAuth && currentSourceAuth !== initialSourceAuth) {
4318
- logWarn("Skipped stale auth sync-back after rate-limit probe; source auth changed in flight.", {
4319
- sourceAuthPath,
4320
- currentRecencyMs: extractAuthRecencyMs(currentSourceAuth),
4321
- updatedRecencyMs: extractAuthRecencyMs(updatedAuth)
4322
- });
4477
+ logWarn(
4478
+ "Skipped stale auth sync-back after rate-limit probe; source auth changed in flight.",
4479
+ {
4480
+ sourceAuthPath,
4481
+ currentRecencyMs: extractAuthRecencyMs(currentSourceAuth),
4482
+ updatedRecencyMs: extractAuthRecencyMs(updatedAuth)
4483
+ }
4484
+ );
4485
+ }
4486
+ }
4487
+ } catch {
4488
+ }
4489
+ await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
4490
+ });
4491
+ }
4492
+ }
4493
+ async function activateResetWindowViaRpc(envOverride, options = {}) {
4494
+ const binaryPath = options.codexPath ?? await requireCodexCli();
4495
+ const tempHome = await import_node_fs5.promises.mkdtemp(
4496
+ import_node_path6.default.join(import_node_os2.default.tmpdir(), "codex-activation-")
4497
+ );
4498
+ const tempAuthPath = import_node_path6.default.join(tempHome, "auth.json");
4499
+ let initialSourceAuth = null;
4500
+ const sourceAuthPath = options.authPath ?? (envOverride?.CODEX_HOME ? import_node_path6.default.join(envOverride.CODEX_HOME, "auth.json") : import_node_path6.default.join(
4501
+ envOverride?.HOME ?? process.env.HOME ?? process.env.USERPROFILE ?? import_node_os2.default.homedir(),
4502
+ ".codex",
4503
+ "auth.json"
4504
+ ));
4505
+ try {
4506
+ initialSourceAuth = await import_node_fs5.promises.readFile(sourceAuthPath, "utf8").catch(() => null);
4507
+ if (!initialSourceAuth) {
4508
+ await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
4509
+ });
4510
+ return { status: "skipped", reason: "auth-missing" };
4511
+ }
4512
+ await import_node_fs5.promises.writeFile(tempAuthPath, initialSourceAuth, "utf8");
4513
+ } catch {
4514
+ await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
4515
+ });
4516
+ return { status: "skipped", reason: "auth-missing" };
4517
+ }
4518
+ const childEnv = {
4519
+ ...process.env,
4520
+ ...envOverride ?? {},
4521
+ HOME: tempHome,
4522
+ USERPROFILE: tempHome,
4523
+ CODEX_HOME: tempHome,
4524
+ CODEX_TELEMETRY_LABEL: "codex-reset-activation",
4525
+ ELECTRON_RUN_AS_NODE: "1"
4526
+ };
4527
+ const command = buildCodexCommand(
4528
+ binaryPath,
4529
+ ["-s", "read-only", "-a", "untrusted", "app-server"],
4530
+ childEnv
4531
+ );
4532
+ const child = (0, import_node_child_process2.spawn)(command.command, command.args, {
4533
+ stdio: ["pipe", "pipe", "pipe"],
4534
+ env: childEnv,
4535
+ shell: command.shell
4536
+ });
4537
+ const rl = import_node_readline.default.createInterface({
4538
+ input: child.stdout,
4539
+ crlfDelay: Infinity
4540
+ });
4541
+ const reader = createRpcMessageReader(rl);
4542
+ let stderrOutput = "";
4543
+ child.stderr?.on("data", (chunk) => {
4544
+ if (stderrOutput.length >= MAX_STDERR_CAPTURE_CHARS) {
4545
+ return;
4546
+ }
4547
+ const text = chunk.toString("utf8");
4548
+ const remaining = MAX_STDERR_CAPTURE_CHARS - stderrOutput.length;
4549
+ stderrOutput += text.slice(0, Math.max(0, remaining));
4550
+ });
4551
+ try {
4552
+ await sendPayload(child, {
4553
+ id: 1,
4554
+ method: "initialize",
4555
+ params: { clientInfo: { name: "codexuse", version: "0.0.0" } }
4556
+ });
4557
+ const initializeResponse = await reader.read(
4558
+ (message) => isRpcResponseForRequest(message, 1),
4559
+ RPC_TIMEOUT_MS
4560
+ );
4561
+ if (initializeResponse.error) {
4562
+ throw new Error(formatRpcError("initialize", initializeResponse.error));
4563
+ }
4564
+ await sendPayload(child, { method: "initialized", params: {} });
4565
+ await sendPayload(child, {
4566
+ id: 2,
4567
+ method: "thread/start",
4568
+ params: {
4569
+ cwd: tempHome,
4570
+ model: ACTIVATION_MODEL,
4571
+ approvalPolicy: "untrusted",
4572
+ sandbox: "read-only",
4573
+ experimentalRawEvents: false
4574
+ }
4575
+ });
4576
+ const threadResponse = await reader.read(
4577
+ (message) => isRpcResponseForRequest(message, 2),
4578
+ RPC_TIMEOUT_MS
4579
+ );
4580
+ if (threadResponse.error) {
4581
+ throw new Error(formatRpcError("thread/start", threadResponse.error));
4582
+ }
4583
+ const threadId = readThreadIdFromResult(threadResponse.result);
4584
+ if (!threadId) {
4585
+ throw new Error("thread/start response did not include a thread id.");
4586
+ }
4587
+ await sendPayload(child, {
4588
+ id: 3,
4589
+ method: "turn/start",
4590
+ params: {
4591
+ threadId,
4592
+ model: ACTIVATION_MODEL,
4593
+ effort: "low",
4594
+ input: [
4595
+ {
4596
+ type: "text",
4597
+ text: ACTIVATION_PROMPT,
4598
+ text_elements: []
4599
+ }
4600
+ ]
4601
+ }
4602
+ });
4603
+ const turnResponse = await reader.read(
4604
+ (message) => isRpcResponseForRequest(message, 3),
4605
+ RPC_TIMEOUT_MS
4606
+ );
4607
+ if (turnResponse.error) {
4608
+ const base = formatRpcError("turn/start", turnResponse.error);
4609
+ const hint = inferRefreshFailureHint(stderrOutput);
4610
+ if (hint && !base.toLowerCase().includes(hint)) {
4611
+ throw new Error(`${base}; ${hint}`);
4612
+ }
4613
+ throw new Error(base);
4614
+ }
4615
+ const turnId = readTurnIdFromResult(turnResponse.result);
4616
+ if (!turnId) {
4617
+ throw new Error("turn/start response did not include a turn id.");
4618
+ }
4619
+ const completed = await reader.read(
4620
+ (message) => message.method === "turn/completed" && readTurnIdFromNotification(message) === turnId || message.method === "codex/event/task_complete" && readLegacyEventTurnId(message) === turnId,
4621
+ ACTIVATION_TURN_TIMEOUT_MS
4622
+ );
4623
+ const turnStatus = readTurnStatusFromNotification(completed);
4624
+ if (turnStatus.status === "failed") {
4625
+ return {
4626
+ status: "failed",
4627
+ reason: turnStatus.reason ?? "turn-failed",
4628
+ threadId,
4629
+ turnId
4630
+ };
4631
+ }
4632
+ return { status: "completed", reason: null, threadId, turnId };
4633
+ } finally {
4634
+ child.kill();
4635
+ reader.dispose();
4636
+ rl.close();
4637
+ try {
4638
+ const updatedAuth = await import_node_fs5.promises.readFile(tempAuthPath, "utf8");
4639
+ if (updatedAuth.trim().length > 0) {
4640
+ const currentSourceAuth = await import_node_fs5.promises.readFile(sourceAuthPath, "utf8").catch(() => null);
4641
+ if (shouldWriteBackAuth(initialSourceAuth, currentSourceAuth, updatedAuth)) {
4642
+ await import_node_fs5.promises.writeFile(sourceAuthPath, updatedAuth, "utf8");
4643
+ } else if (currentSourceAuth && currentSourceAuth !== updatedAuth && currentSourceAuth !== initialSourceAuth) {
4644
+ logWarn(
4645
+ "Skipped stale auth sync-back after reset-window activation; source auth changed in flight.",
4646
+ {
4647
+ sourceAuthPath,
4648
+ currentRecencyMs: extractAuthRecencyMs(currentSourceAuth),
4649
+ updatedRecencyMs: extractAuthRecencyMs(updatedAuth)
4650
+ }
4651
+ );
4323
4652
  }
4324
4653
  }
4325
4654
  } catch {
@@ -5868,6 +6197,25 @@ var ProfileManager = class {
5868
6197
  });
5869
6198
  }
5870
6199
  }
6200
+ async activateResetWindow(name, options = {}) {
6201
+ const profileName = this.normalizeProfileName(name);
6202
+ try {
6203
+ return await this.enqueueProfileOperation(
6204
+ profileName,
6205
+ () => this.runWithPreparedProfileHome(
6206
+ profileName,
6207
+ (env) => activateResetWindowViaRpc(env, { codexPath: options.codexPath }),
6208
+ { syncFromActiveAuthBeforeAction: false }
6209
+ )
6210
+ );
6211
+ } finally {
6212
+ await this.enqueueAuthSwap(async () => {
6213
+ await this.syncActiveAuthFromProfileIfCurrent(profileName);
6214
+ }).catch((error) => {
6215
+ logWarn(`Failed to sync active auth after reset-window activation for '${profileName}':`, error);
6216
+ });
6217
+ }
6218
+ }
5871
6219
  /**
5872
6220
  * Rename a profile
5873
6221
  */
@@ -6320,7 +6668,7 @@ var MODEL_SLUG_ALIASES = {
6320
6668
  function asRecord2(value) {
6321
6669
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
6322
6670
  }
6323
- function asString3(value) {
6671
+ function asString4(value) {
6324
6672
  if (typeof value !== "string") {
6325
6673
  return null;
6326
6674
  }
@@ -6331,7 +6679,7 @@ function asNumber(value) {
6331
6679
  return typeof value === "number" && Number.isFinite(value) ? value : null;
6332
6680
  }
6333
6681
  function normalizeIsoString(value) {
6334
- const normalized = asString3(value);
6682
+ const normalized = asString4(value);
6335
6683
  if (!normalized) {
6336
6684
  return null;
6337
6685
  }
@@ -6343,7 +6691,7 @@ function normalizeStringArray(value) {
6343
6691
  const result = [];
6344
6692
  const seen = /* @__PURE__ */ new Set();
6345
6693
  for (const entry of input) {
6346
- const normalized = asString3(entry);
6694
+ const normalized = asString4(entry);
6347
6695
  if (!normalized || seen.has(normalized)) {
6348
6696
  continue;
6349
6697
  }
@@ -6353,7 +6701,7 @@ function normalizeStringArray(value) {
6353
6701
  return result;
6354
6702
  }
6355
6703
  function normalizeReasoningEffort(value) {
6356
- const normalized = asString3(value)?.toLowerCase() ?? null;
6704
+ const normalized = asString4(value)?.toLowerCase() ?? null;
6357
6705
  return normalized && normalized.length > 0 ? normalized : null;
6358
6706
  }
6359
6707
  function normalizeRoutingStrategy(value) {
@@ -6387,7 +6735,7 @@ function normalizeAccountPoolExposedModels(value, fallbackToDefault) {
6387
6735
  const seen = /* @__PURE__ */ new Set();
6388
6736
  const input = Array.isArray(value) ? value : [];
6389
6737
  for (const entry of input) {
6390
- const raw = asString3(entry);
6738
+ const raw = asString4(entry);
6391
6739
  const normalized = normalizeCodexModelSlug(raw) ?? raw;
6392
6740
  if (!normalized || seen.has(normalized)) {
6393
6741
  continue;
@@ -6503,8 +6851,8 @@ function normalizeSessionStatus(value) {
6503
6851
  }
6504
6852
  function normalizeApiKeyRecord(id, value) {
6505
6853
  const record = asRecord2(value);
6506
- const tokenHash = asString3(record.tokenHash);
6507
- const tokenPreview = asString3(record.tokenPreview);
6854
+ const tokenHash = asString4(record.tokenHash);
6855
+ const tokenPreview = asString4(record.tokenPreview);
6508
6856
  const createdAt = normalizeIsoString(record.createdAt);
6509
6857
  if (!tokenHash || !tokenPreview || !createdAt) {
6510
6858
  return null;
@@ -6520,7 +6868,7 @@ function normalizeApiKeyRecord(id, value) {
6520
6868
  }
6521
6869
  function normalizeLegacySessionRecord(id, value) {
6522
6870
  const record = asRecord2(value);
6523
- const profileName = asString3(record.profileName);
6871
+ const profileName = asString4(record.profileName);
6524
6872
  const createdAt = normalizeIsoString(record.createdAt);
6525
6873
  const lastUsedAt = normalizeIsoString(record.lastUsedAt);
6526
6874
  if (!profileName || !createdAt || !lastUsedAt) {
@@ -6530,16 +6878,16 @@ function normalizeLegacySessionRecord(id, value) {
6530
6878
  return {
6531
6879
  id,
6532
6880
  affinityKind,
6533
- affinityKey: asString3(record.affinityKey),
6881
+ affinityKey: asString4(record.affinityKey),
6534
6882
  profileName,
6535
- threadId: asString3(record.threadId) ?? id,
6536
- model: asString3(record.model),
6883
+ threadId: asString4(record.threadId) ?? id,
6884
+ model: asString4(record.model),
6537
6885
  status: normalizeSessionStatus(record.status),
6538
- lastError: asString3(record.lastError),
6886
+ lastError: asString4(record.lastError),
6539
6887
  createdAt,
6540
6888
  lastUsedAt,
6541
6889
  expiresAt: normalizeIsoString(record.expiresAt),
6542
- lastResponseId: asString3(record.lastResponseId),
6890
+ lastResponseId: asString4(record.lastResponseId),
6543
6891
  responseIds: normalizeStringArray(record.responseIds).slice(0, MAX_RESPONSE_IDS_PER_SESSION)
6544
6892
  };
6545
6893
  }
@@ -6561,7 +6909,7 @@ function normalizeLegacyStore(value) {
6561
6909
  }
6562
6910
  const responseIndex = {};
6563
6911
  for (const [responseId, sessionId] of Object.entries(asRecord2(record.responseIndex))) {
6564
- const normalizedSessionId = asString3(sessionId);
6912
+ const normalizedSessionId = asString4(sessionId);
6565
6913
  if (normalizedSessionId) {
6566
6914
  responseIndex[responseId] = normalizedSessionId;
6567
6915
  }
@@ -6576,7 +6924,7 @@ function normalizeLegacyStore(value) {
6576
6924
  }
6577
6925
  function normalizeSessionRecord(id, value) {
6578
6926
  const record = asRecord2(value);
6579
- const activeSegmentId = asString3(record.activeSegmentId);
6927
+ const activeSegmentId = asString4(record.activeSegmentId);
6580
6928
  const createdAt = normalizeIsoString(record.createdAt);
6581
6929
  const lastUsedAt = normalizeIsoString(record.lastUsedAt);
6582
6930
  if (!activeSegmentId || !createdAt || !lastUsedAt) {
@@ -6586,25 +6934,25 @@ function normalizeSessionRecord(id, value) {
6586
6934
  return {
6587
6935
  id,
6588
6936
  affinityKind,
6589
- affinityKey: asString3(record.affinityKey),
6937
+ affinityKey: asString4(record.affinityKey),
6590
6938
  activeSegmentId,
6591
6939
  segmentIds: normalizeStringArray(record.segmentIds),
6592
- model: asString3(record.model),
6940
+ model: asString4(record.model),
6593
6941
  status: normalizeSessionStatus(record.status),
6594
- lastError: asString3(record.lastError),
6942
+ lastError: asString4(record.lastError),
6595
6943
  createdAt,
6596
6944
  lastUsedAt,
6597
6945
  expiresAt: normalizeIsoString(record.expiresAt),
6598
- lastResponseId: asString3(record.lastResponseId),
6946
+ lastResponseId: asString4(record.lastResponseId),
6599
6947
  responseIds: normalizeStringArray(record.responseIds).slice(0, MAX_RESPONSE_IDS_PER_SESSION),
6600
6948
  rolloverCount: asNumber(record.rolloverCount) ?? 0,
6601
- lastRolloverReason: asString3(record.lastRolloverReason)
6949
+ lastRolloverReason: asString4(record.lastRolloverReason)
6602
6950
  };
6603
6951
  }
6604
6952
  function normalizeSegmentRecord(id, value) {
6605
6953
  const record = asRecord2(value);
6606
- const sessionId = asString3(record.sessionId);
6607
- const profileName = asString3(record.profileName);
6954
+ const sessionId = asString4(record.sessionId);
6955
+ const profileName = asString4(record.profileName);
6608
6956
  const createdAt = normalizeIsoString(record.createdAt);
6609
6957
  const lastUsedAt = normalizeIsoString(record.lastUsedAt);
6610
6958
  if (!sessionId || !profileName || !createdAt || !lastUsedAt) {
@@ -6620,8 +6968,8 @@ function normalizeSegmentRecord(id, value) {
6620
6968
  }
6621
6969
  function normalizeResponseIndexRecord(value) {
6622
6970
  const record = asRecord2(value);
6623
- const sessionId = asString3(record.sessionId);
6624
- const segmentId = asString3(record.segmentId);
6971
+ const sessionId = asString4(record.sessionId);
6972
+ const segmentId = asString4(record.segmentId);
6625
6973
  const createdAt = normalizeIsoString(record.createdAt) ?? (/* @__PURE__ */ new Date(0)).toISOString();
6626
6974
  if (!sessionId || !segmentId) {
6627
6975
  return null;
@@ -7296,7 +7644,7 @@ async function handleAccountPoolCommand(args, version) {
7296
7644
  params,
7297
7645
  key: "accountPoolExposedModels",
7298
7646
  defaultValues: DEFAULT_ACCOUNT_POOL_EXPOSED_MODELS,
7299
- normalizeValue: (value) => normalizeCodexModelSlug(value) ?? asString3(value)
7647
+ normalizeValue: (value) => normalizeCodexModelSlug(value) ?? asString4(value)
7300
7648
  });
7301
7649
  return;
7302
7650
  case "reasoning":
@@ -8653,228 +9001,227 @@ async function getOfficialCodexProfileInstances() {
8653
9001
  };
8654
9002
  }
8655
9003
  function launchOfficialCodexProfileInstance(options) {
8656
- return enqueueProfileAction(async () => {
8657
- if (process.platform !== "darwin") {
8658
- return {
8659
- status: "skipped",
8660
- profileName: options.profileName,
8661
- instance: null,
8662
- reason: "unsupported-platform"
8663
- };
8664
- }
8665
- const { candidate, mainPids } = await resolveCodexAppTarget();
8666
- if (!candidate) {
8667
- return {
8668
- status: "skipped",
8669
- profileName: options.profileName,
8670
- instance: null,
8671
- reason: "official-codex-app-not-found"
8672
- };
8673
- }
8674
- const existing = await readManagedInstance(options.profileName);
8675
- if (existing) {
8676
- const rows = await readProcessRows();
8677
- const runtime = await resolveInstanceRuntimeState({ instance: existing, candidate, rows });
8678
- if (runtime.running) {
8679
- const verified = {
8680
- ...existing,
8681
- profileHome: existing.profileHome ?? options.profileHome,
8682
- appServerPid: runtime.appServerPid,
8683
- lastVerifiedAt: Date.now(),
8684
- lastStatus: "already-running",
8685
- lastError: null
8686
- };
8687
- await patchManagedInstance(verified);
8688
- return {
8689
- status: "already-running",
8690
- profileName: options.profileName,
8691
- instance: managedInstanceToPayload(
8692
- verified,
8693
- true,
8694
- runtime.appServerPid,
8695
- runtime.startedAt
8696
- ),
8697
- reason: null
8698
- };
8699
- }
8700
- }
8701
- const launch = await openCodexWithProfileHome(
8702
- candidate,
8703
- options.profileHome,
8704
- options.profileName,
8705
- new Set(mainPids)
8706
- );
8707
- if (!launch.opened) {
8708
- const failed = {
8709
- profileName: options.profileName,
8710
- profileKey: options.profileKey,
8711
- profileHome: options.profileHome,
8712
- appPath: candidate.appPath,
8713
- bundleId: candidate.bundleId,
8714
- pid: null,
8715
- appServerPid: null,
8716
- launchedAt: null,
8717
- lastVerifiedAt: null,
8718
- lastStatus: "failed",
8719
- lastError: "open-failed"
8720
- };
8721
- await patchManagedInstance(failed);
8722
- return {
8723
- status: "failed",
8724
- profileName: options.profileName,
8725
- instance: managedInstanceToPayload(failed, false),
8726
- reason: "open-failed"
8727
- };
8728
- }
8729
- const launchedPid = launch.pid;
8730
- if (launchedPid === null) {
8731
- const failed = {
8732
- profileName: options.profileName,
8733
- profileKey: options.profileKey,
8734
- profileHome: options.profileHome,
8735
- appPath: candidate.appPath,
8736
- bundleId: candidate.bundleId,
8737
- pid: null,
8738
- appServerPid: null,
8739
- launchedAt: null,
8740
- lastVerifiedAt: null,
8741
- lastStatus: "failed",
8742
- lastError: "launch-timeout"
8743
- };
8744
- await patchManagedInstance(failed);
8745
- return {
8746
- status: "failed",
8747
- profileName: options.profileName,
8748
- instance: managedInstanceToPayload(failed, false),
8749
- reason: "launch-timeout"
8750
- };
8751
- }
8752
- const appServerPid = await waitForAppServerPid(
8753
- launchedPid,
8754
- options.profileHome
8755
- );
8756
- if (appServerPid === null) {
8757
- const failed = {
8758
- profileName: options.profileName,
8759
- profileKey: options.profileKey,
8760
- profileHome: options.profileHome,
8761
- appPath: candidate.appPath,
8762
- bundleId: candidate.bundleId,
8763
- pid: null,
8764
- appServerPid: null,
8765
- launchedAt: null,
9004
+ return enqueueProfileAction(() => launchOfficialCodexProfileInstanceOnce(options));
9005
+ }
9006
+ async function launchOfficialCodexProfileInstanceOnce(options) {
9007
+ if (process.platform !== "darwin") {
9008
+ return {
9009
+ status: "skipped",
9010
+ profileName: options.profileName,
9011
+ instance: null,
9012
+ reason: "unsupported-platform"
9013
+ };
9014
+ }
9015
+ const { candidate, mainPids } = await resolveCodexAppTarget();
9016
+ if (!candidate) {
9017
+ return {
9018
+ status: "skipped",
9019
+ profileName: options.profileName,
9020
+ instance: null,
9021
+ reason: "official-codex-app-not-found"
9022
+ };
9023
+ }
9024
+ const existing = await readManagedInstance(options.profileName);
9025
+ if (existing) {
9026
+ const rows = await readProcessRows();
9027
+ const runtime = await resolveInstanceRuntimeState({ instance: existing, candidate, rows });
9028
+ if (runtime.running) {
9029
+ const verified = {
9030
+ ...existing,
9031
+ profileHome: existing.profileHome ?? options.profileHome,
9032
+ appServerPid: runtime.appServerPid,
8766
9033
  lastVerifiedAt: Date.now(),
8767
- lastStatus: "failed",
8768
- lastError: "app-server-not-verified"
9034
+ lastStatus: "already-running",
9035
+ lastError: null
8769
9036
  };
8770
- await patchManagedInstance(failed);
9037
+ await patchManagedInstance(verified);
8771
9038
  return {
8772
- status: "failed",
9039
+ status: "already-running",
8773
9040
  profileName: options.profileName,
8774
- instance: managedInstanceToPayload(failed, false),
8775
- reason: "app-server-not-verified"
9041
+ instance: managedInstanceToPayload(
9042
+ verified,
9043
+ true,
9044
+ runtime.appServerPid,
9045
+ runtime.startedAt
9046
+ ),
9047
+ reason: null
8776
9048
  };
8777
9049
  }
8778
- const now = Date.now();
8779
- const instance = {
9050
+ }
9051
+ const launch = await openCodexWithProfileHome(
9052
+ candidate,
9053
+ options.profileHome,
9054
+ options.profileName,
9055
+ new Set(mainPids)
9056
+ );
9057
+ if (!launch.opened) {
9058
+ const failed = {
8780
9059
  profileName: options.profileName,
8781
9060
  profileKey: options.profileKey,
8782
9061
  profileHome: options.profileHome,
8783
9062
  appPath: candidate.appPath,
8784
9063
  bundleId: candidate.bundleId,
8785
- pid: launchedPid,
8786
- appServerPid,
8787
- launchedAt: now,
8788
- lastVerifiedAt: now,
8789
- lastStatus: "started",
8790
- lastError: null
9064
+ pid: null,
9065
+ appServerPid: null,
9066
+ launchedAt: null,
9067
+ lastVerifiedAt: null,
9068
+ lastStatus: "failed",
9069
+ lastError: "open-failed"
8791
9070
  };
8792
- await patchManagedInstance(instance);
9071
+ await patchManagedInstance(failed);
8793
9072
  return {
8794
- status: "started",
9073
+ status: "failed",
8795
9074
  profileName: options.profileName,
8796
- instance: managedInstanceToPayload(instance, true, appServerPid),
8797
- reason: null
9075
+ instance: managedInstanceToPayload(failed, false),
9076
+ reason: "open-failed"
8798
9077
  };
8799
- });
9078
+ }
9079
+ const launchedPid = launch.pid;
9080
+ if (launchedPid === null) {
9081
+ const failed = {
9082
+ profileName: options.profileName,
9083
+ profileKey: options.profileKey,
9084
+ profileHome: options.profileHome,
9085
+ appPath: candidate.appPath,
9086
+ bundleId: candidate.bundleId,
9087
+ pid: null,
9088
+ appServerPid: null,
9089
+ launchedAt: null,
9090
+ lastVerifiedAt: null,
9091
+ lastStatus: "failed",
9092
+ lastError: "launch-timeout"
9093
+ };
9094
+ await patchManagedInstance(failed);
9095
+ return {
9096
+ status: "failed",
9097
+ profileName: options.profileName,
9098
+ instance: managedInstanceToPayload(failed, false),
9099
+ reason: "launch-timeout"
9100
+ };
9101
+ }
9102
+ const appServerPid = await waitForAppServerPid(
9103
+ launchedPid,
9104
+ options.profileHome
9105
+ );
9106
+ if (appServerPid === null) {
9107
+ const failed = {
9108
+ profileName: options.profileName,
9109
+ profileKey: options.profileKey,
9110
+ profileHome: options.profileHome,
9111
+ appPath: candidate.appPath,
9112
+ bundleId: candidate.bundleId,
9113
+ pid: null,
9114
+ appServerPid: null,
9115
+ launchedAt: null,
9116
+ lastVerifiedAt: Date.now(),
9117
+ lastStatus: "failed",
9118
+ lastError: "app-server-not-verified"
9119
+ };
9120
+ await patchManagedInstance(failed);
9121
+ return {
9122
+ status: "failed",
9123
+ profileName: options.profileName,
9124
+ instance: managedInstanceToPayload(failed, false),
9125
+ reason: "app-server-not-verified"
9126
+ };
9127
+ }
9128
+ const now = Date.now();
9129
+ const instance = {
9130
+ profileName: options.profileName,
9131
+ profileKey: options.profileKey,
9132
+ profileHome: options.profileHome,
9133
+ appPath: candidate.appPath,
9134
+ bundleId: candidate.bundleId,
9135
+ pid: launchedPid,
9136
+ appServerPid,
9137
+ launchedAt: now,
9138
+ lastVerifiedAt: now,
9139
+ lastStatus: "started",
9140
+ lastError: null
9141
+ };
9142
+ await patchManagedInstance(instance);
9143
+ return {
9144
+ status: "started",
9145
+ profileName: options.profileName,
9146
+ instance: managedInstanceToPayload(instance, true, appServerPid),
9147
+ reason: null
9148
+ };
8800
9149
  }
8801
- function stopOfficialCodexProfileInstance(profileName) {
8802
- return enqueueProfileAction(async () => {
8803
- const existing = await readManagedInstance(profileName);
8804
- if (!existing) {
8805
- return {
8806
- status: "not-running",
8807
- profileName,
8808
- instance: null,
8809
- reason: "not-managed"
8810
- };
8811
- }
8812
- const { candidate } = await resolveCodexAppTarget();
8813
- if (!candidate) {
8814
- const stopped2 = {
8815
- ...existing,
8816
- pid: null,
8817
- appServerPid: null,
8818
- lastVerifiedAt: Date.now(),
8819
- lastStatus: "not-running",
8820
- lastError: "official-codex-app-not-found"
8821
- };
8822
- await patchManagedInstance(stopped2);
8823
- return {
8824
- status: "not-running",
8825
- profileName,
8826
- instance: managedInstanceToPayload(stopped2, false),
8827
- reason: "official-codex-app-not-found"
8828
- };
8829
- }
8830
- const rows = await readProcessRows();
8831
- const runtime = await resolveInstanceRuntimeState({ instance: existing, candidate, rows });
8832
- if (!runtime.running || !existing.pid) {
8833
- const stopped2 = {
8834
- ...existing,
8835
- pid: null,
8836
- appServerPid: null,
8837
- lastVerifiedAt: Date.now(),
8838
- lastStatus: "not-running",
8839
- lastError: null
8840
- };
8841
- await patchManagedInstance(stopped2);
8842
- return {
8843
- status: "not-running",
8844
- profileName,
8845
- instance: managedInstanceToPayload(stopped2, false),
8846
- reason: null
8847
- };
8848
- }
8849
- const tree = [existing.pid, ...getDescendantPids(existing.pid, rows)].filter((pid, index, all) => all.indexOf(pid) === index).sort((a, b) => b - a);
8850
- await signalPids(tree, "SIGTERM");
8851
- const exited = await waitForMainPidExit(existing.pid, 5e3);
8852
- if (!exited) {
8853
- await signalPids(tree, "SIGKILL");
8854
- await waitForMainPidExit(existing.pid, EXIT_WAIT_MS);
8855
- }
8856
- const stillRunning = (await readProcessRows()).some((row) => row.pid === existing.pid);
8857
- const stopped = {
9150
+ async function stopOfficialCodexProfileInstanceOnce(profileName) {
9151
+ const existing = await readManagedInstance(profileName);
9152
+ if (!existing) {
9153
+ return {
9154
+ status: "not-running",
9155
+ profileName,
9156
+ instance: null,
9157
+ reason: "not-managed"
9158
+ };
9159
+ }
9160
+ const { candidate } = await resolveCodexAppTarget();
9161
+ if (!candidate) {
9162
+ const stopped2 = {
8858
9163
  ...existing,
8859
- pid: stillRunning ? existing.pid : null,
8860
- appServerPid: stillRunning ? runtime.appServerPid : null,
9164
+ pid: null,
9165
+ appServerPid: null,
8861
9166
  lastVerifiedAt: Date.now(),
8862
- lastStatus: stillRunning ? "failed" : "stopped",
8863
- lastError: stillRunning ? "stop-timeout" : null
9167
+ lastStatus: "not-running",
9168
+ lastError: "official-codex-app-not-found"
8864
9169
  };
8865
- await patchManagedInstance(stopped);
9170
+ await patchManagedInstance(stopped2);
8866
9171
  return {
8867
- status: stillRunning ? "failed" : "stopped",
9172
+ status: "not-running",
8868
9173
  profileName,
8869
- instance: managedInstanceToPayload(
8870
- stopped,
8871
- stillRunning,
8872
- stopped.appServerPid,
8873
- runtime.startedAt
8874
- ),
8875
- reason: stillRunning ? "stop-timeout" : null
9174
+ instance: managedInstanceToPayload(stopped2, false),
9175
+ reason: "official-codex-app-not-found"
8876
9176
  };
8877
- });
9177
+ }
9178
+ const rows = await readProcessRows();
9179
+ const runtime = await resolveInstanceRuntimeState({ instance: existing, candidate, rows });
9180
+ if (!runtime.running || !existing.pid) {
9181
+ const stopped2 = {
9182
+ ...existing,
9183
+ pid: null,
9184
+ appServerPid: null,
9185
+ lastVerifiedAt: Date.now(),
9186
+ lastStatus: "not-running",
9187
+ lastError: null
9188
+ };
9189
+ await patchManagedInstance(stopped2);
9190
+ return {
9191
+ status: "not-running",
9192
+ profileName,
9193
+ instance: managedInstanceToPayload(stopped2, false),
9194
+ reason: null
9195
+ };
9196
+ }
9197
+ const tree = [existing.pid, ...getDescendantPids(existing.pid, rows)].filter((pid, index, all) => all.indexOf(pid) === index).sort((a, b) => b - a);
9198
+ await signalPids(tree, "SIGTERM");
9199
+ const exited = await waitForMainPidExit(existing.pid, 5e3);
9200
+ if (!exited) {
9201
+ await signalPids(tree, "SIGKILL");
9202
+ await waitForMainPidExit(existing.pid, EXIT_WAIT_MS);
9203
+ }
9204
+ const stillRunning = (await readProcessRows()).some((row) => row.pid === existing.pid);
9205
+ const stopped = {
9206
+ ...existing,
9207
+ pid: stillRunning ? existing.pid : null,
9208
+ appServerPid: stillRunning ? runtime.appServerPid : null,
9209
+ lastVerifiedAt: Date.now(),
9210
+ lastStatus: stillRunning ? "failed" : "stopped",
9211
+ lastError: stillRunning ? "stop-timeout" : null
9212
+ };
9213
+ await patchManagedInstance(stopped);
9214
+ return {
9215
+ status: stillRunning ? "failed" : "stopped",
9216
+ profileName,
9217
+ instance: managedInstanceToPayload(
9218
+ stopped,
9219
+ stillRunning,
9220
+ stopped.appServerPid,
9221
+ runtime.startedAt
9222
+ ),
9223
+ reason: stillRunning ? "stop-timeout" : null
9224
+ };
8878
9225
  }
8879
9226
  function stopOfficialCodexObservedProfileInstance(profileName, pid, appServerPid) {
8880
9227
  return enqueueProfileAction(async () => {
@@ -8930,15 +9277,17 @@ function stopOfficialCodexObservedProfileInstance(profileName, pid, appServerPid
8930
9277
  });
8931
9278
  }
8932
9279
  async function restartOfficialCodexProfileInstance(options) {
8933
- const stopped = await stopOfficialCodexProfileInstance(options.profileName);
8934
- if (stopped.status === "failed") {
8935
- return stopped;
8936
- }
8937
- const launched = await launchOfficialCodexProfileInstance(options);
8938
- return {
8939
- ...launched,
8940
- status: launched.status === "started" ? "restarted" : launched.status
8941
- };
9280
+ return enqueueProfileAction(async () => {
9281
+ const stopped = await stopOfficialCodexProfileInstanceOnce(options.profileName);
9282
+ if (stopped.status === "failed") {
9283
+ return stopped;
9284
+ }
9285
+ const launched = await launchOfficialCodexProfileInstanceOnce(options);
9286
+ return {
9287
+ ...launched,
9288
+ status: launched.status === "started" ? "restarted" : launched.status
9289
+ };
9290
+ });
8942
9291
  }
8943
9292
 
8944
9293
  // src/commands/profile.ts
@@ -9941,7 +10290,7 @@ var import_node_path15 = __toESM(require("path"), 1);
9941
10290
  var CLOUD_SYNC_SCHEMA_VERSION = 1;
9942
10291
 
9943
10292
  // ../../packages/shared/src/core/type-guards.ts
9944
- function isRecord4(value) {
10293
+ function isRecord5(value) {
9945
10294
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
9946
10295
  }
9947
10296
  function toIsoOrNull(value) {
@@ -9979,10 +10328,10 @@ function buildSyncUrl(pathname) {
9979
10328
  return `${baseUrl}${normalizedPath}`;
9980
10329
  }
9981
10330
  function normalizeSnapshot(value) {
9982
- if (!isRecord4(value)) {
10331
+ if (!isRecord5(value)) {
9983
10332
  return null;
9984
10333
  }
9985
- if (isRecord4(value.snapshot)) {
10334
+ if (isRecord5(value.snapshot)) {
9986
10335
  const nested = normalizeSnapshot(value.snapshot);
9987
10336
  if (nested) {
9988
10337
  return nested;
@@ -9997,9 +10346,9 @@ function normalizeSnapshot(value) {
9997
10346
  return null;
9998
10347
  }
9999
10348
  const rawProfiles = Array.isArray(value.profiles) ? value.profiles : [];
10000
- const profiles = rawProfiles.map((entry) => isRecord4(entry) ? entry : null).filter((entry) => Boolean(entry)).map((entry) => {
10001
- const data = isRecord4(entry.data) ? entry.data : {};
10002
- const metadata = isRecord4(entry.metadata) ? entry.metadata : void 0;
10349
+ const profiles = rawProfiles.map((entry) => isRecord5(entry) ? entry : null).filter((entry) => Boolean(entry)).map((entry) => {
10350
+ const data = isRecord5(entry.data) ? entry.data : {};
10351
+ const metadata = isRecord5(entry.metadata) ? entry.metadata : void 0;
10003
10352
  return {
10004
10353
  name: typeof entry.name === "string" ? entry.name : "",
10005
10354
  displayName: typeof entry.displayName === "string" ? entry.displayName : null,
@@ -10015,7 +10364,7 @@ function normalizeSnapshot(value) {
10015
10364
  };
10016
10365
  }).filter((entry) => entry.name.trim().length > 0);
10017
10366
  const rawSettings = value.settingsJson;
10018
- const settingsJson = isRecord4(rawSettings) ? rawSettings : null;
10367
+ const settingsJson = isRecord5(rawSettings) ? rawSettings : null;
10019
10368
  return {
10020
10369
  schemaVersion: CLOUD_SYNC_SCHEMA_VERSION,
10021
10370
  updatedAt,
@@ -10199,7 +10548,7 @@ var FALLBACK_FEATURE_KEYS = [
10199
10548
  ];
10200
10549
  var metadataCache = null;
10201
10550
  var metadataCacheAt = 0;
10202
- function isRecord5(value) {
10551
+ function isRecord6(value) {
10203
10552
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
10204
10553
  }
10205
10554
  function uniqueSorted(values) {
@@ -10264,16 +10613,16 @@ function parseFeatureCatalog(output) {
10264
10613
  }
10265
10614
  function parseSchemaKeys(schemaRaw) {
10266
10615
  const parsed = JSON.parse(schemaRaw);
10267
- if (!isRecord5(parsed)) {
10616
+ if (!isRecord6(parsed)) {
10268
10617
  return {
10269
10618
  topLevelKeys: FALLBACK_SCHEMA_TOP_LEVEL_KEYS,
10270
10619
  featureKeys: FALLBACK_FEATURE_KEYS
10271
10620
  };
10272
10621
  }
10273
- const properties = isRecord5(parsed.properties) ? parsed.properties : {};
10622
+ const properties = isRecord6(parsed.properties) ? parsed.properties : {};
10274
10623
  const topLevelKeys = uniqueSorted(Object.keys(properties));
10275
- const features = isRecord5(properties.features) ? properties.features : {};
10276
- const featureProperties = isRecord5(features.properties) ? features.properties : {};
10624
+ const features = isRecord6(properties.features) ? properties.features : {};
10625
+ const featureProperties = isRecord6(features.properties) ? features.properties : {};
10277
10626
  const featureKeys = uniqueSorted(Object.keys(featureProperties));
10278
10627
  return {
10279
10628
  topLevelKeys: topLevelKeys.length > 0 ? topLevelKeys : FALLBACK_SCHEMA_TOP_LEVEL_KEYS,
@@ -11059,15 +11408,15 @@ var SYNC_SIZE_WARN_BYTES = 1 * 1024 * 1024;
11059
11408
  var SYNC_SIZE_MAX_BYTES = 5 * 1024 * 1024;
11060
11409
  var MB_DIVISOR = 1024 * 1024;
11061
11410
  function mapProfilesFromAppState(raw) {
11062
- if (!isRecord4(raw)) {
11411
+ if (!isRecord5(raw)) {
11063
11412
  return [];
11064
11413
  }
11065
11414
  const profiles = [];
11066
11415
  for (const [name, value] of Object.entries(raw)) {
11067
- if (!isRecord4(value)) {
11416
+ if (!isRecord5(value)) {
11068
11417
  continue;
11069
11418
  }
11070
- const data = isRecord4(value.data) ? value.data : null;
11419
+ const data = isRecord5(value.data) ? value.data : null;
11071
11420
  if (!data) {
11072
11421
  continue;
11073
11422
  }
@@ -11079,7 +11428,7 @@ function mapProfilesFromAppState(raw) {
11079
11428
  name: normalizedName,
11080
11429
  displayName: typeof value.displayName === "string" ? value.displayName : null,
11081
11430
  data,
11082
- metadata: isRecord4(value.metadata) ? value.metadata : void 0,
11431
+ metadata: isRecord5(value.metadata) ? value.metadata : void 0,
11083
11432
  accountId: typeof value.accountId === "string" ? value.accountId : null,
11084
11433
  workspaceId: typeof value.workspaceId === "string" ? value.workspaceId : null,
11085
11434
  workspaceName: typeof value.workspaceName === "string" ? value.workspaceName : null,
@@ -11093,7 +11442,7 @@ function mapProfilesFromAppState(raw) {
11093
11442
  }
11094
11443
  function summarizeSnapshot(snapshot) {
11095
11444
  const configBytes = typeof snapshot.configTomlContent === "string" ? snapshot.configTomlContent.length : 0;
11096
- const settingsKeys = isRecord4(snapshot.settingsJson) ? Object.keys(snapshot.settingsJson).length : 0;
11445
+ const settingsKeys = isRecord5(snapshot.settingsJson) ? Object.keys(snapshot.settingsJson).length : 0;
11097
11446
  return {
11098
11447
  profiles: snapshot.profiles.length,
11099
11448
  configBytes,
@@ -11198,7 +11547,7 @@ async function buildLocalSnapshot(profileManager, options = {}) {
11198
11547
  const settingsJson = await readCodexSettingsJsonRaw();
11199
11548
  const hasProfiles = profiles.length > 0;
11200
11549
  const hasConfig = typeof config.content === "string" && config.content.trim().length > 0;
11201
- const hasSettings = isRecord4(settingsJson) && Object.keys(settingsJson).length > 0;
11550
+ const hasSettings = isRecord5(settingsJson) && Object.keys(settingsJson).length > 0;
11202
11551
  if (enforcePushGuards && !hasProfiles && !hasConfig && !hasSettings) {
11203
11552
  throw new Error("Refusing to push an empty cloud sync snapshot.");
11204
11553
  }
@@ -11222,7 +11571,7 @@ async function applyRemoteSnapshot(profileManager, snapshot) {
11222
11571
  codexHomePath: runtimeContext.codexHomePath
11223
11572
  });
11224
11573
  }
11225
- if (snapshot.settingsJson && isRecord4(snapshot.settingsJson)) {
11574
+ if (snapshot.settingsJson && isRecord5(snapshot.settingsJson)) {
11226
11575
  await writeCodexSettingsJsonRaw(snapshot.settingsJson);
11227
11576
  } else {
11228
11577
  await writeCodexSettingsJsonRaw({});
@@ -11475,10 +11824,10 @@ var LEGACY_SKILL_CACHE_DIR = "skill-cache";
11475
11824
  var LEGACY_SKILLS_REPOS_FILE = "repos.json";
11476
11825
  var LEGACY_SKILL_MANIFEST = ".codexuse-skill.json";
11477
11826
  var LEGACY_LICENSE_SECRET_FILE2 = "license.secret";
11478
- function isRecord6(value) {
11827
+ function isRecord7(value) {
11479
11828
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
11480
11829
  }
11481
- function asString4(value) {
11830
+ function asString5(value) {
11482
11831
  if (typeof value !== "string") {
11483
11832
  return null;
11484
11833
  }
@@ -11647,7 +11996,7 @@ function pickAutoRoll(raw) {
11647
11996
  }
11648
11997
  }
11649
11998
  function parseLegacyLicense(raw) {
11650
- if (!isRecord6(raw)) {
11999
+ if (!isRecord7(raw)) {
11651
12000
  return {
11652
12001
  licenseKey: null,
11653
12002
  purchaseEmail: null,
@@ -11658,25 +12007,25 @@ function parseLegacyLicense(raw) {
11658
12007
  signature: null
11659
12008
  };
11660
12009
  }
11661
- const statusCandidate = asString4(raw.status);
12010
+ const statusCandidate = asString5(raw.status);
11662
12011
  const status = ["inactive", "active", "grace", "error"].includes(statusCandidate ?? "") ? statusCandidate : "inactive";
11663
12012
  return {
11664
- licenseKey: asString4(raw.licenseKey ?? raw.license_key),
11665
- purchaseEmail: asString4(raw.purchaseEmail ?? raw.purchase_email),
11666
- lastVerifiedAt: asString4(raw.lastVerifiedAt ?? raw.last_verified_at),
11667
- nextCheckAt: asString4(raw.nextCheckAt ?? raw.next_check_at),
11668
- lastVerificationError: asString4(raw.lastVerificationError ?? raw.last_verification_error),
12013
+ licenseKey: asString5(raw.licenseKey ?? raw.license_key),
12014
+ purchaseEmail: asString5(raw.purchaseEmail ?? raw.purchase_email),
12015
+ lastVerifiedAt: asString5(raw.lastVerifiedAt ?? raw.last_verified_at),
12016
+ nextCheckAt: asString5(raw.nextCheckAt ?? raw.next_check_at),
12017
+ lastVerificationError: asString5(raw.lastVerificationError ?? raw.last_verification_error),
11669
12018
  status,
11670
- signature: asString4(raw.signature)
12019
+ signature: asString5(raw.signature)
11671
12020
  };
11672
12021
  }
11673
12022
  function parseLegacyProfileRecord(name, raw) {
11674
- if (!isRecord6(raw)) {
12023
+ if (!isRecord7(raw)) {
11675
12024
  return null;
11676
12025
  }
11677
12026
  const dataRaw = raw.data;
11678
12027
  let data = null;
11679
- if (isRecord6(dataRaw)) {
12028
+ if (isRecord7(dataRaw)) {
11680
12029
  data = dataRaw;
11681
12030
  } else if (typeof dataRaw === "string") {
11682
12031
  try {
@@ -11690,31 +12039,31 @@ function parseLegacyProfileRecord(name, raw) {
11690
12039
  }
11691
12040
  return {
11692
12041
  name,
11693
- displayName: asString4(raw.displayName ?? raw.display_name) ?? name,
12042
+ displayName: asString5(raw.displayName ?? raw.display_name) ?? name,
11694
12043
  data,
11695
- metadata: isRecord6(raw.metadata) ? raw.metadata : void 0,
11696
- accountId: asString4(raw.accountId ?? raw.account_id),
11697
- workspaceId: asString4(raw.workspaceId ?? raw.workspace_id),
11698
- workspaceName: asString4(raw.workspaceName ?? raw.workspace_name),
11699
- email: asString4(raw.email),
11700
- authMethod: asString4(raw.authMethod ?? raw.auth_method),
11701
- createdAt: asString4(raw.createdAt ?? raw.created_at),
11702
- updatedAt: asString4(raw.updatedAt ?? raw.updated_at)
12044
+ metadata: isRecord7(raw.metadata) ? raw.metadata : void 0,
12045
+ accountId: asString5(raw.accountId ?? raw.account_id),
12046
+ workspaceId: asString5(raw.workspaceId ?? raw.workspace_id),
12047
+ workspaceName: asString5(raw.workspaceName ?? raw.workspace_name),
12048
+ email: asString5(raw.email),
12049
+ authMethod: asString5(raw.authMethod ?? raw.auth_method),
12050
+ createdAt: asString5(raw.createdAt ?? raw.created_at),
12051
+ updatedAt: asString5(raw.updatedAt ?? raw.updated_at)
11703
12052
  };
11704
12053
  }
11705
12054
  async function loadLegacySettingsPatch() {
11706
12055
  const filePath = resolveLegacyPath(LEGACY_SETTINGS_FILE);
11707
12056
  const raw = await readJsonFileIfExists(filePath);
11708
- if (!isRecord6(raw)) {
12057
+ if (!isRecord7(raw)) {
11709
12058
  return {};
11710
12059
  }
11711
12060
  const autoRoll = pickAutoRoll(raw.autoRoll ?? raw.auto_roll);
11712
12061
  const license = parseLegacyLicense(raw.license ?? raw.license_data ?? raw.license_state);
11713
12062
  return {
11714
12063
  app: {
11715
- lastAppVersion: asString4(raw.lastAppVersion ?? raw.last_app_version),
11716
- pendingUpdateVersion: asString4(raw.pendingUpdateVersion ?? raw.pending_update_version),
11717
- lastProfileName: asString4(raw.lastProfileName ?? raw.last_profile_name)
12064
+ lastAppVersion: asString5(raw.lastAppVersion ?? raw.last_app_version),
12065
+ pendingUpdateVersion: asString5(raw.pendingUpdateVersion ?? raw.pending_update_version),
12066
+ lastProfileName: asString5(raw.lastProfileName ?? raw.last_profile_name)
11718
12067
  },
11719
12068
  license,
11720
12069
  autoRoll: autoRoll ? {
@@ -11732,22 +12081,22 @@ async function loadLegacySettingsPatch() {
11732
12081
  async function loadLegacySyncPatch() {
11733
12082
  const filePath = resolveLegacyPath(LEGACY_SYNC_STATE_FILE);
11734
12083
  const raw = await readJsonFileIfExists(filePath);
11735
- if (!isRecord6(raw)) {
12084
+ if (!isRecord7(raw)) {
11736
12085
  return {};
11737
12086
  }
11738
12087
  return {
11739
12088
  sync: {
11740
- lastPushAt: asString4(raw.lastPushAt),
11741
- lastPullAt: asString4(raw.lastPullAt),
11742
- lastError: asString4(raw.lastError),
11743
- remoteUpdatedAt: asString4(raw.remoteUpdatedAt)
12089
+ lastPushAt: asString5(raw.lastPushAt),
12090
+ lastPullAt: asString5(raw.lastPullAt),
12091
+ lastError: asString5(raw.lastError),
12092
+ remoteUpdatedAt: asString5(raw.remoteUpdatedAt)
11744
12093
  }
11745
12094
  };
11746
12095
  }
11747
12096
  async function loadLegacyAppSettingsParityPatch() {
11748
12097
  const filePath = import_node_path16.default.join(getUserDataDir(), LEGACY_APP_SETTINGS_PARITY_FILE);
11749
12098
  const raw = await readJsonFileIfExists(filePath);
11750
- if (!isRecord6(raw)) {
12099
+ if (!isRecord7(raw)) {
11751
12100
  return {};
11752
12101
  }
11753
12102
  return {
@@ -11787,21 +12136,21 @@ async function loadLegacyProfilesPatch() {
11787
12136
  return { profilesByName };
11788
12137
  }
11789
12138
  function parseSkillInstallMetadata(raw) {
11790
- if (!isRecord6(raw)) {
12139
+ if (!isRecord7(raw)) {
11791
12140
  return null;
11792
12141
  }
11793
- const id = asString4(raw.id);
12142
+ const id = asString5(raw.id);
11794
12143
  if (!id) {
11795
12144
  return null;
11796
12145
  }
11797
12146
  return {
11798
12147
  id,
11799
- repo: asString4(raw.repo),
11800
- repoPath: asString4(raw.repoPath),
11801
- sourceLabel: asString4(raw.sourceLabel),
12148
+ repo: asString5(raw.repo),
12149
+ repoPath: asString5(raw.repoPath),
12150
+ sourceLabel: asString5(raw.sourceLabel),
11802
12151
  sourceType: raw.sourceType === "official" || raw.sourceType === "community" || raw.sourceType === "local" ? raw.sourceType : void 0,
11803
- viewUrl: asString4(raw.viewUrl),
11804
- createdAt: asString4(raw.createdAt)
12152
+ viewUrl: asString5(raw.viewUrl),
12153
+ createdAt: asString5(raw.createdAt)
11805
12154
  };
11806
12155
  }
11807
12156
  async function loadLegacySkillsPatch() {
@@ -11832,7 +12181,7 @@ async function loadLegacySkillsPatch() {
11832
12181
  }
11833
12182
  installsBySlug[entry.name] = parsed;
11834
12183
  }
11835
- const sources = isRecord6(reposRaw) && Array.isArray(reposRaw.sources) ? reposRaw.sources : [];
12184
+ const sources = isRecord7(reposRaw) && Array.isArray(reposRaw.sources) ? reposRaw.sources : [];
11836
12185
  if (sources.length === 0 && Object.keys(installsBySlug).length === 0) {
11837
12186
  return {};
11838
12187
  }
@@ -11864,7 +12213,7 @@ function mergeLegacyLocalStoragePatch(payload) {
11864
12213
  }
11865
12214
  };
11866
12215
  const settingsStorage = payload["settings-storage"];
11867
- if (isRecord6(settingsStorage)) {
12216
+ if (isRecord7(settingsStorage)) {
11868
12217
  const nextExcludeFolders = Array.isArray(settingsStorage.excludeFolders) ? settingsStorage.excludeFolders.filter((item) => typeof item === "string") : void 0;
11869
12218
  const nextBeep = typeof settingsStorage.enableTaskCompleteBeep === "boolean" ? settingsStorage.enableTaskCompleteBeep : void 0;
11870
12219
  const nextSleep = typeof settingsStorage.preventSleepDuringTasks === "boolean" ? settingsStorage.preventSleepDuringTasks : void 0;
@@ -11883,15 +12232,15 @@ function mergeLegacyLocalStoragePatch(payload) {
11883
12232
  markSkippedIfPresent("provider", hasKey2("provider"));
11884
12233
  markSkippedIfPresent("sandbox-storage", hasKey2("sandbox-storage"));
11885
12234
  const projectSettings = payload["project-settings-storage"];
11886
- if (isRecord6(projectSettings) && isRecord6(projectSettings.settingsByPath)) {
12235
+ if (isRecord7(projectSettings) && isRecord7(projectSettings.settingsByPath)) {
11887
12236
  patch.workspaceSettingsByPath = projectSettings.settingsByPath;
11888
12237
  markSkippedIfPresent("project-settings-storage", true);
11889
12238
  } else {
11890
12239
  markSkippedIfPresent("project-settings-storage", false);
11891
12240
  }
11892
12241
  const folder = payload["folder-storage"];
11893
- if (isRecord6(folder)) {
11894
- const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(isRecord6) : void 0;
12242
+ if (isRecord7(folder)) {
12243
+ const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(isRecord7) : void 0;
11895
12244
  const pinnedPaths = Array.isArray(folder.pinnedPaths) ? folder.pinnedPaths.filter((item) => typeof item === "string") : void 0;
11896
12245
  patch.preferences = {
11897
12246
  ...patch.preferences ?? {},
@@ -11904,12 +12253,12 @@ function mergeLegacyLocalStoragePatch(payload) {
11904
12253
  }
11905
12254
  const categories = payload["conversation-categories-storage"];
11906
12255
  let consumedCategories = false;
11907
- if (isRecord6(categories)) {
11908
- if (isRecord6(categories.categoriesByCwd)) {
12256
+ if (isRecord7(categories)) {
12257
+ if (isRecord7(categories.categoriesByCwd)) {
11909
12258
  patch.conversationCategoriesByCwd = categories.categoriesByCwd;
11910
12259
  consumedCategories = true;
11911
12260
  }
11912
- if (isRecord6(categories.conversationCategoryByCwd)) {
12261
+ if (isRecord7(categories.conversationCategoryByCwd)) {
11913
12262
  patch.conversationCategoryAssignmentsByCwd = categories.conversationCategoryByCwd;
11914
12263
  consumedCategories = true;
11915
12264
  }
@@ -12132,7 +12481,7 @@ async function importLegacyLocalStorageOnce(payload) {
12132
12481
  if (current.migration.status === "pending") {
12133
12482
  return { completed: false, importedKeys: [], skippedKeys: [] };
12134
12483
  }
12135
- if (!payload || !isRecord6(payload)) {
12484
+ if (!payload || !isRecord7(payload)) {
12136
12485
  return { completed: true, importedKeys: [], skippedKeys: [] };
12137
12486
  }
12138
12487
  const { patch, consumedKeys, skippedKeys } = mergeLegacyLocalStoragePatch(payload);
@@ -12200,7 +12549,7 @@ async function ensureCliStorageReady() {
12200
12549
  }
12201
12550
 
12202
12551
  // src/app/main.ts
12203
- var VERSION = true ? "3.9.8" : "0.0.0";
12552
+ var VERSION = true ? "3.9.9" : "0.0.0";
12204
12553
  async function runCli() {
12205
12554
  const args = process.argv.slice(2);
12206
12555
  if (args.length === 0) {