codexuse-cli 2.4.19 → 2.5.1

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
@@ -80,22 +80,6 @@ function normalizeAutoRollSettings(raw) {
80
80
  };
81
81
  }
82
82
 
83
- // ../../lib/codex-cli-channel.ts
84
- var KNOWN_CHANNELS = /* @__PURE__ */ new Set(["stable", "alpha"]);
85
- function parseCodexCliChannel(value) {
86
- if (typeof value !== "string") {
87
- return null;
88
- }
89
- const normalized = value.trim().toLowerCase();
90
- if (!normalized) {
91
- return null;
92
- }
93
- return KNOWN_CHANNELS.has(normalized) ? normalized : null;
94
- }
95
- function normalizeCodexCliChannel(value, fallback = "stable") {
96
- return parseCodexCliChannel(value) ?? fallback;
97
- }
98
-
99
83
  // ../../lib/app-state.ts
100
84
  var import_node_fs = require("fs");
101
85
  var import_node_async_hooks = require("async_hooks");
@@ -129,6 +113,22 @@ function normalizeChatHistoryScrollbackItems(value) {
129
113
  return CHAT_SCROLLBACK_DEFAULT;
130
114
  }
131
115
 
116
+ // ../../lib/commit-message-prompt.ts
117
+ var 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.
118
+
119
+ Changes:
120
+ {diff}`;
121
+ function normalizeLineEndings(value) {
122
+ return value.replace(/\r\n/g, "\n");
123
+ }
124
+ function normalizeCommitMessagePrompt(value) {
125
+ if (typeof value !== "string") {
126
+ return null;
127
+ }
128
+ const normalized = normalizeLineEndings(value).trim();
129
+ return normalized.length > 0 ? normalized : null;
130
+ }
131
+
132
132
  // ../../lib/app-state.ts
133
133
  var APP_STATE_FILE = "app-state.json";
134
134
  var APP_NAME = "codexuse-desktop";
@@ -176,7 +176,6 @@ function createDefaultAppState() {
176
176
  app: {
177
177
  lastAppVersion: null,
178
178
  pendingUpdateVersion: null,
179
- cliChannel: "stable",
180
179
  lastProfileName: null
181
180
  },
182
181
  license: {
@@ -207,16 +206,22 @@ function createDefaultAppState() {
207
206
  chatHistoryScrollbackItems: CHAT_SCROLLBACK_DEFAULT,
208
207
  systemNotificationsEnabled: true,
209
208
  subagentSystemNotificationsEnabled: true,
210
- dictationEnabled: true,
211
- dictationHoldKey: "",
212
- dictationPreferredLanguage: null,
213
- speakRepliesEnabled: false,
214
209
  folderHistory: [],
215
210
  pinnedPaths: []
216
211
  },
217
- projectSettingsByPath: {},
212
+ runtimeSettings: {},
213
+ workspaceSettingsByPath: {},
218
214
  conversationCategoriesByCwd: {},
219
215
  conversationCategoryAssignmentsByCwd: {},
216
+ git: {
217
+ commitMessagePrompt: DEFAULT_COMMIT_MESSAGE_PROMPT,
218
+ commitMessageModelId: null
219
+ },
220
+ agents: {
221
+ multiAgentEnabled: false,
222
+ maxThreads: 6,
223
+ maxDepth: 1
224
+ },
220
225
  skills: {
221
226
  sources: [],
222
227
  installsBySlug: {}
@@ -273,10 +278,17 @@ function normalizeAppState(raw) {
273
278
  if (merged.autoRoll.switchThreshold <= merged.autoRoll.warningThreshold || merged.autoRoll.switchThreshold > 100) {
274
279
  merged.autoRoll.switchThreshold = Math.min(100, Math.max(merged.autoRoll.warningThreshold + 1, 95));
275
280
  }
276
- merged.app.cliChannel = merged.app.cliChannel === "alpha" ? "alpha" : "stable";
277
281
  merged.app.lastAppVersion = asString(merged.app.lastAppVersion);
278
282
  merged.app.pendingUpdateVersion = asString(merged.app.pendingUpdateVersion);
279
283
  merged.app.lastProfileName = asString(merged.app.lastProfileName);
284
+ {
285
+ const allowedAppKeys = new Set(Object.keys(defaults.app));
286
+ for (const key of Object.keys(merged.app)) {
287
+ if (!allowedAppKeys.has(key)) {
288
+ delete merged.app[key];
289
+ }
290
+ }
291
+ }
280
292
  merged.license.licenseKey = asString(merged.license.licenseKey);
281
293
  merged.license.purchaseEmail = asString(merged.license.purchaseEmail);
282
294
  merged.license.lastVerifiedAt = asString(merged.license.lastVerifiedAt);
@@ -324,15 +336,55 @@ function normalizeAppState(raw) {
324
336
  if (!Array.isArray(merged.preferences.pinnedPaths)) {
325
337
  merged.preferences.pinnedPaths = [];
326
338
  }
327
- if (!isRecord(merged.projectSettingsByPath)) {
328
- merged.projectSettingsByPath = {};
339
+ {
340
+ const allowedPreferenceKeys = new Set(Object.keys(defaults.preferences));
341
+ for (const key of Object.keys(merged.preferences)) {
342
+ if (!allowedPreferenceKeys.has(key)) {
343
+ delete merged.preferences[key];
344
+ }
345
+ }
346
+ }
347
+ if (!isRecord(merged.runtimeSettings)) {
348
+ merged.runtimeSettings = {};
349
+ }
350
+ const legacyProjectSettingsByPath = isRecord(
351
+ raw.projectSettingsByPath
352
+ ) ? raw.projectSettingsByPath : null;
353
+ if (!isRecord(merged.workspaceSettingsByPath)) {
354
+ merged.workspaceSettingsByPath = {};
329
355
  }
356
+ if (legacyProjectSettingsByPath) {
357
+ merged.workspaceSettingsByPath = {
358
+ ...legacyProjectSettingsByPath,
359
+ ...merged.workspaceSettingsByPath
360
+ };
361
+ }
362
+ delete merged.projectSettingsByPath;
330
363
  if (!isRecord(merged.conversationCategoriesByCwd)) {
331
364
  merged.conversationCategoriesByCwd = {};
332
365
  }
333
366
  if (!isRecord(merged.conversationCategoryAssignmentsByCwd)) {
334
367
  merged.conversationCategoryAssignmentsByCwd = {};
335
368
  }
369
+ if (!isRecord(merged.git)) {
370
+ merged.git = clone(defaults.git);
371
+ }
372
+ merged.git.commitMessagePrompt = normalizeCommitMessagePrompt(merged.git.commitMessagePrompt) ?? DEFAULT_COMMIT_MESSAGE_PROMPT;
373
+ merged.git.commitMessageModelId = asString(merged.git.commitMessageModelId);
374
+ if (!isRecord(merged.agents)) {
375
+ merged.agents = clone(defaults.agents);
376
+ }
377
+ if (typeof merged.agents.multiAgentEnabled !== "boolean") {
378
+ merged.agents.multiAgentEnabled = defaults.agents.multiAgentEnabled;
379
+ }
380
+ if (!Number.isFinite(merged.agents.maxThreads)) {
381
+ merged.agents.maxThreads = defaults.agents.maxThreads;
382
+ }
383
+ merged.agents.maxThreads = Math.max(1, Math.min(12, Math.round(merged.agents.maxThreads)));
384
+ if (!Number.isFinite(merged.agents.maxDepth)) {
385
+ merged.agents.maxDepth = defaults.agents.maxDepth;
386
+ }
387
+ merged.agents.maxDepth = Math.max(1, Math.min(4, Math.round(merged.agents.maxDepth)));
336
388
  if (!isRecord(merged.skills)) {
337
389
  merged.skills = clone(defaults.skills);
338
390
  }
@@ -445,7 +497,7 @@ async function withWriteLock(task) {
445
497
  return task();
446
498
  }
447
499
  const previous = writeLock;
448
- let release = null;
500
+ let release;
449
501
  writeLock = new Promise((resolve) => {
450
502
  release = resolve;
451
503
  });
@@ -453,7 +505,9 @@ async function withWriteLock(task) {
453
505
  try {
454
506
  return await writeLockContext.run(true, task);
455
507
  } finally {
456
- release?.();
508
+ if (release) {
509
+ release();
510
+ }
457
511
  }
458
512
  }
459
513
  async function initializeAppState(userDataDir) {
@@ -570,17 +624,12 @@ async function getStoredAutoRollSettings() {
570
624
  const state = await getAppState();
571
625
  return normalizeAutoRollSettings(state.autoRoll);
572
626
  }
573
- async function getCodexCliChannel() {
574
- const state = await getAppState();
575
- return normalizeCodexCliChannel(state.app.cliChannel);
576
- }
577
627
  async function readCodexSettingsJsonRaw() {
578
628
  const state = await getAppState();
579
629
  return {
580
630
  lastProfileName: state.app.lastProfileName,
581
631
  lastAppVersion: state.app.lastAppVersion,
582
632
  pendingUpdateVersion: state.app.pendingUpdateVersion,
583
- cliChannel: state.app.cliChannel,
584
633
  autoRoll: state.autoRoll,
585
634
  license: state.license,
586
635
  providers: state.providers.list,
@@ -598,9 +647,13 @@ async function readCodexSettingsJsonRaw() {
598
647
  subagentSystemNotificationsEnabled: state.preferences.subagentSystemNotificationsEnabled,
599
648
  folderHistory: state.preferences.folderHistory,
600
649
  pinnedPaths: state.preferences.pinnedPaths,
601
- projectSettingsByPath: state.projectSettingsByPath,
650
+ workspaceSettingsByPath: state.workspaceSettingsByPath,
651
+ // Legacy compatibility for older consumers.
652
+ projectSettingsByPath: state.workspaceSettingsByPath,
602
653
  categoriesByCwd: state.conversationCategoriesByCwd,
603
654
  conversationCategoryByCwd: state.conversationCategoryAssignmentsByCwd,
655
+ git: state.git,
656
+ agents: state.agents,
604
657
  sync: state.sync
605
658
  };
606
659
  }
@@ -610,13 +663,11 @@ async function writeCodexSettingsJsonRaw(payload) {
610
663
  }
611
664
  const autoRoll = parseAutoRoll(payload.autoRoll ?? payload.auto_roll);
612
665
  const license = parseStoredLicense(payload.license);
613
- const cliChannel = parseCodexCliChannel(payload.cliChannel ?? payload.cli_channel);
614
666
  await patchAppState({
615
667
  app: {
616
668
  lastProfileName: asString2(payload.lastProfileName ?? payload.last_profile_name),
617
669
  lastAppVersion: asString2(payload.lastAppVersion ?? payload.last_app_version),
618
- pendingUpdateVersion: asString2(payload.pendingUpdateVersion ?? payload.pending_update_version),
619
- cliChannel: cliChannel ?? void 0
670
+ pendingUpdateVersion: asString2(payload.pendingUpdateVersion ?? payload.pending_update_version)
620
671
  },
621
672
  autoRoll: autoRoll ? {
622
673
  enabled: autoRoll.enabled,
@@ -653,9 +704,11 @@ async function writeCodexSettingsJsonRaw(payload) {
653
704
  folderHistory: Array.isArray(payload.folderHistory) ? payload.folderHistory : void 0,
654
705
  pinnedPaths: Array.isArray(payload.pinnedPaths) ? payload.pinnedPaths : void 0
655
706
  },
656
- projectSettingsByPath: isRecord2(payload.projectSettingsByPath) ? payload.projectSettingsByPath : void 0,
707
+ workspaceSettingsByPath: isRecord2(payload.workspaceSettingsByPath) ? payload.workspaceSettingsByPath : isRecord2(payload.projectSettingsByPath) ? payload.projectSettingsByPath : void 0,
657
708
  conversationCategoriesByCwd: isRecord2(payload.categoriesByCwd) ? payload.categoriesByCwd : void 0,
658
709
  conversationCategoryAssignmentsByCwd: isRecord2(payload.conversationCategoryByCwd) ? payload.conversationCategoryByCwd : void 0,
710
+ git: isRecord2(payload.git) ? payload.git : void 0,
711
+ agents: isRecord2(payload.agents) ? payload.agents : void 0,
659
712
  sync: isRecord2(payload.sync) ? payload.sync : void 0
660
713
  });
661
714
  }
@@ -2726,8 +2779,8 @@ var import_node_path4 = __toESM(require("path"));
2726
2779
  // ../../lib/codex-cli.ts
2727
2780
  var import_node_fs3 = require("fs");
2728
2781
  var import_node_path3 = __toESM(require("path"));
2782
+ var STABLE_CHANNEL = "stable";
2729
2783
  var cachedStatus = null;
2730
- var cachedChannel = null;
2731
2784
  function fileExists(candidate) {
2732
2785
  if (!candidate) {
2733
2786
  return null;
@@ -2742,11 +2795,11 @@ function fileExists(candidate) {
2742
2795
  }
2743
2796
  return null;
2744
2797
  }
2745
- function resolveBundledCodexBinary(channel) {
2798
+ function resolveBundledCodexBinary() {
2746
2799
  const candidates = [];
2747
2800
  const processWithResources = process;
2748
2801
  const resourcesPath = processWithResources.resourcesPath;
2749
- const packageSegments = channel === "alpha" ? ["@openai", "codex-alpha"] : ["@openai", "codex"];
2802
+ const packageSegments = ["@openai", "codex"];
2750
2803
  if (resourcesPath) {
2751
2804
  candidates.push(
2752
2805
  import_node_path3.default.join(resourcesPath, "app.asar.unpacked", "node_modules", ...packageSegments, "bin", "codex.js")
@@ -2766,51 +2819,30 @@ function resolveBundledCodexBinary(channel) {
2766
2819
  }
2767
2820
  return null;
2768
2821
  }
2769
- function resolveBundledCodexBinaryWithFallback(requestedChannel) {
2770
- const direct = resolveBundledCodexBinary(requestedChannel);
2771
- if (direct) {
2772
- return { path: direct, resolvedChannel: requestedChannel, fallbackUsed: false };
2773
- }
2774
- if (requestedChannel === "alpha") {
2775
- const stable = resolveBundledCodexBinary("stable");
2776
- if (stable) {
2777
- return { path: stable, resolvedChannel: "stable", fallbackUsed: true };
2778
- }
2779
- }
2780
- return { path: null, resolvedChannel: null, fallbackUsed: false };
2781
- }
2782
- function buildUnavailableStatus(channel) {
2783
- const channelLabel = channel === "alpha" ? "alpha " : "";
2784
- const channelSuffix = channel === "alpha" ? " Switch to Stable in Settings or reinstall CodexUse to restore the CLI." : " Reinstall CodexUse to restore the CLI.";
2822
+ function buildUnavailableStatus() {
2785
2823
  return {
2786
2824
  available: false,
2787
2825
  path: null,
2788
- reason: `Bundled ${channelLabel}Codex CLI is missing.${channelSuffix}`,
2826
+ reason: "Bundled Codex CLI is missing. Reinstall CodexUse to restore the CLI.",
2789
2827
  source: null,
2790
- channel,
2791
- requestedChannel: channel,
2792
- fallbackUsed: false
2828
+ channel: STABLE_CHANNEL
2793
2829
  };
2794
2830
  }
2795
- function evaluateCodexCliStatus(requestedChannel) {
2796
- const resolved = resolveBundledCodexBinaryWithFallback(requestedChannel);
2797
- if (resolved.path && resolved.resolvedChannel) {
2831
+ function evaluateCodexCliStatus() {
2832
+ const resolvedPath = resolveBundledCodexBinary();
2833
+ if (resolvedPath) {
2798
2834
  return {
2799
2835
  available: true,
2800
- path: resolved.path,
2836
+ path: resolvedPath,
2801
2837
  reason: null,
2802
2838
  source: "bundled",
2803
- channel: resolved.resolvedChannel,
2804
- requestedChannel,
2805
- fallbackUsed: resolved.fallbackUsed
2839
+ channel: STABLE_CHANNEL
2806
2840
  };
2807
2841
  }
2808
- return buildUnavailableStatus(requestedChannel);
2842
+ return buildUnavailableStatus();
2809
2843
  }
2810
2844
  async function refreshCodexStatus() {
2811
- const channel = await getCodexCliChannel();
2812
- cachedChannel = channel;
2813
- cachedStatus = evaluateCodexCliStatus(channel);
2845
+ cachedStatus = evaluateCodexCliStatus();
2814
2846
  return { ...cachedStatus };
2815
2847
  }
2816
2848
  var CodexCliMissingError = class extends Error {
@@ -3016,8 +3048,7 @@ async function readSchemaFromLocal() {
3016
3048
  const candidates = [
3017
3049
  process.env.CODEX_CONFIG_SCHEMA_PATH,
3018
3050
  import_node_path4.default.join(process.cwd(), "codex-rs", "core", "config.schema.json"),
3019
- import_node_path4.default.join(process.cwd(), "node_modules", "@openai", "codex", "codex-rs", "core", "config.schema.json"),
3020
- import_node_path4.default.join(process.cwd(), "node_modules", "@openai", "codex-alpha", "codex-rs", "core", "config.schema.json")
3051
+ import_node_path4.default.join(process.cwd(), "node_modules", "@openai", "codex", "codex-rs", "core", "config.schema.json")
3021
3052
  ].filter((candidate) => Boolean(candidate));
3022
3053
  for (const candidate of candidates) {
3023
3054
  try {
@@ -3223,7 +3254,7 @@ async function ensureConfigDirExists(filePath) {
3223
3254
  const dir = import_node_path5.default.dirname(filePath);
3224
3255
  await (0, import_promises2.mkdir)(dir, { recursive: true });
3225
3256
  }
3226
- function normalizeLineEndings(content) {
3257
+ function normalizeLineEndings2(content) {
3227
3258
  return content.replace(/\r\n/g, "\n");
3228
3259
  }
3229
3260
  function ensureTrailingNewline(content) {
@@ -3520,7 +3551,7 @@ async function readConfigContent() {
3520
3551
  const content = await (0, import_promises2.readFile)(configPath, "utf8");
3521
3552
  return {
3522
3553
  exists: true,
3523
- content: normalizeLineEndings(content)
3554
+ content: normalizeLineEndings2(content)
3524
3555
  };
3525
3556
  } catch (error) {
3526
3557
  const nodeError = error;
@@ -3536,7 +3567,7 @@ async function readConfigContent() {
3536
3567
  async function writeConfigContent(content) {
3537
3568
  const configPath = getConfigPath();
3538
3569
  await ensureConfigDirExists(configPath);
3539
- const normalized = ensureTrailingNewline(normalizeLineEndings(content));
3570
+ const normalized = ensureTrailingNewline(normalizeLineEndings2(content));
3540
3571
  await (0, import_promises2.writeFile)(configPath, normalized, "utf8");
3541
3572
  }
3542
3573
  async function getUpdatedAt(configPath, exists) {
@@ -3582,7 +3613,7 @@ async function getCodexConfigSnapshot() {
3582
3613
  return buildSnapshot(content, exists);
3583
3614
  }
3584
3615
  async function saveCodexConfigContent(content) {
3585
- const normalized = ensureTrailingNewline(normalizeLineEndings(content));
3616
+ const normalized = ensureTrailingNewline(normalizeLineEndings2(content));
3586
3617
  const parsed = tryParseToml(normalized);
3587
3618
  if (!parsed.data) {
3588
3619
  throw new Error(parsed.error ?? "config.toml contains invalid TOML syntax.");
@@ -3935,10 +3966,7 @@ var import_node_child_process2 = require("child_process");
3935
3966
  var import_node_fs5 = require("fs");
3936
3967
  var import_node_path7 = __toESM(require("path"));
3937
3968
  var ENV_HINTS = ["CODEX_BINARY", "CODEX_CLI_PATH", "CODEX_PATH"];
3938
- var NODE_MODULE_CANDIDATES = [
3939
- ["@openai", "codex"],
3940
- ["@openai", "codex-alpha"]
3941
- ];
3969
+ var NODE_MODULE_CANDIDATES = [["@openai", "codex"]];
3942
3970
  function fileExists2(candidate) {
3943
3971
  if (!candidate) return null;
3944
3972
  const resolved = import_node_path7.default.resolve(candidate);
@@ -4507,14 +4535,12 @@ async function loadLegacySettingsPatch() {
4507
4535
  if (!isRecord5(raw)) {
4508
4536
  return {};
4509
4537
  }
4510
- const cliChannel = parseCodexCliChannel(raw.cliChannel ?? raw.cli_channel);
4511
4538
  const autoRoll = pickAutoRoll(raw.autoRoll ?? raw.auto_roll);
4512
4539
  const license = parseLegacyLicense(raw.license ?? raw.license_data ?? raw.license_state);
4513
4540
  return {
4514
4541
  app: {
4515
4542
  lastAppVersion: asString3(raw.lastAppVersion ?? raw.last_app_version),
4516
4543
  pendingUpdateVersion: asString3(raw.pendingUpdateVersion ?? raw.pending_update_version),
4517
- cliChannel: cliChannel ?? void 0,
4518
4544
  lastProfileName: asString3(raw.lastProfileName ?? raw.last_profile_name)
4519
4545
  },
4520
4546
  license,
@@ -4709,7 +4735,7 @@ function mergeLegacyLocalStoragePatch(payload) {
4709
4735
  }
4710
4736
  const projectSettings = payload["project-settings-storage"];
4711
4737
  if (isRecord5(projectSettings) && isRecord5(projectSettings.settingsByPath)) {
4712
- patch.projectSettingsByPath = projectSettings.settingsByPath;
4738
+ patch.workspaceSettingsByPath = projectSettings.settingsByPath;
4713
4739
  markSkippedIfPresent("project-settings-storage", true);
4714
4740
  } else {
4715
4741
  markSkippedIfPresent("project-settings-storage", false);
@@ -4838,9 +4864,9 @@ async function runStorageMigrationV1() {
4838
4864
  preferences: { ...acc.preferences ?? {}, ...patch.preferences ?? {} },
4839
4865
  sync: { ...acc.sync ?? {}, ...patch.sync ?? {} },
4840
4866
  profilesByName: { ...acc.profilesByName ?? {}, ...patch.profilesByName ?? {} },
4841
- projectSettingsByPath: {
4842
- ...acc.projectSettingsByPath ?? {},
4843
- ...patch.projectSettingsByPath ?? {}
4867
+ workspaceSettingsByPath: {
4868
+ ...acc.workspaceSettingsByPath ?? {},
4869
+ ...patch.workspaceSettingsByPath ?? {}
4844
4870
  },
4845
4871
  conversationCategoriesByCwd: {
4846
4872
  ...acc.conversationCategoriesByCwd ?? {},
@@ -4889,9 +4915,9 @@ async function runStorageMigrationV1() {
4889
4915
  ...state.profilesByName,
4890
4916
  ...mergedPatch.profilesByName ?? {}
4891
4917
  },
4892
- projectSettingsByPath: {
4893
- ...state.projectSettingsByPath,
4894
- ...mergedPatch.projectSettingsByPath ?? {}
4918
+ workspaceSettingsByPath: {
4919
+ ...state.workspaceSettingsByPath,
4920
+ ...mergedPatch.workspaceSettingsByPath ?? {}
4895
4921
  },
4896
4922
  conversationCategoriesByCwd: {
4897
4923
  ...state.conversationCategoriesByCwd,
@@ -4978,9 +5004,9 @@ async function importLegacyLocalStorageOnce(payload) {
4978
5004
  }
4979
5005
  },
4980
5006
  preferences: { ...state.preferences, ...patch.preferences ?? {} },
4981
- projectSettingsByPath: {
4982
- ...state.projectSettingsByPath,
4983
- ...patch.projectSettingsByPath ?? {}
5007
+ workspaceSettingsByPath: {
5008
+ ...state.workspaceSettingsByPath,
5009
+ ...patch.workspaceSettingsByPath ?? {}
4984
5010
  },
4985
5011
  conversationCategoriesByCwd: {
4986
5012
  ...state.conversationCategoriesByCwd,
@@ -5010,7 +5036,7 @@ async function importLegacyLocalStorageOnce(payload) {
5010
5036
  }
5011
5037
 
5012
5038
  // src/index.ts
5013
- var VERSION = true ? "2.4.19" : "0.0.0";
5039
+ var VERSION = true ? "2.5.1" : "0.0.0";
5014
5040
  var cliStorageReadyPromise = null;
5015
5041
  async function ensureCliStorageReady() {
5016
5042
  if (cliStorageReadyPromise) {