zcf 3.2.3 → 3.3.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.
Files changed (41) hide show
  1. package/README.md +102 -14
  2. package/dist/chunks/api-providers.mjs +76 -0
  3. package/dist/chunks/claude-code-config-manager.mjs +21 -7
  4. package/dist/chunks/claude-code-incremental-manager.mjs +210 -14
  5. package/dist/chunks/codex-config-switch.mjs +197 -12
  6. package/dist/chunks/codex-provider-manager.mjs +20 -9
  7. package/dist/chunks/codex-uninstaller.mjs +19 -24
  8. package/dist/chunks/commands.mjs +1 -1
  9. package/dist/chunks/features.mjs +637 -0
  10. package/dist/chunks/simple-config.mjs +182 -29
  11. package/dist/cli.mjs +13 -613
  12. package/dist/i18n/locales/en/api.json +6 -1
  13. package/dist/i18n/locales/en/codex.json +7 -0
  14. package/dist/i18n/locales/en/errors.json +1 -0
  15. package/dist/i18n/locales/en/multi-config.json +8 -1
  16. package/dist/i18n/locales/zh-CN/api.json +6 -1
  17. package/dist/i18n/locales/zh-CN/codex.json +7 -0
  18. package/dist/i18n/locales/zh-CN/errors.json +1 -0
  19. package/dist/i18n/locales/zh-CN/multi-config.json +8 -1
  20. package/dist/index.d.mts +13 -1
  21. package/dist/index.d.ts +13 -1
  22. package/dist/index.mjs +1 -1
  23. package/package.json +1 -1
  24. package/templates/CLAUDE.md +191 -0
  25. package/templates/claude-code/CLAUDE.md +1 -0
  26. package/templates/claude-code/en/output-styles/engineer-professional.md +2 -1
  27. package/templates/claude-code/en/output-styles/laowang-engineer.md +1 -0
  28. package/templates/claude-code/en/output-styles/nekomata-engineer.md +1 -0
  29. package/templates/claude-code/en/output-styles/ojousama-engineer.md +1 -0
  30. package/templates/claude-code/zh-CN/output-styles/engineer-professional.md +2 -1
  31. package/templates/claude-code/zh-CN/output-styles/laowang-engineer.md +1 -0
  32. package/templates/claude-code/zh-CN/output-styles/nekomata-engineer.md +1 -0
  33. package/templates/claude-code/zh-CN/output-styles/ojousama-engineer.md +1 -0
  34. package/templates/codex/en/system-prompt/engineer-professional.md +2 -1
  35. package/templates/codex/en/system-prompt/laowang-engineer.md +1 -0
  36. package/templates/codex/en/system-prompt/nekomata-engineer.md +1 -0
  37. package/templates/codex/en/system-prompt/ojousama-engineer.md +1 -0
  38. package/templates/codex/zh-CN/system-prompt/engineer-professional.md +2 -1
  39. package/templates/codex/zh-CN/system-prompt/laowang-engineer.md +1 -0
  40. package/templates/codex/zh-CN/system-prompt/nekomata-engineer.md +1 -0
  41. package/templates/codex/zh-CN/system-prompt/ojousama-engineer.md +1 -0
@@ -1,7 +1,7 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { a4 as ensureI18nInitialized, af as detectConfigManagementMode, a5 as i18n, a6 as addNumbersToChoices } from './simple-config.mjs';
4
- import { deleteProviders, editExistingProvider, addProviderToExisting } from './codex-provider-manager.mjs';
3
+ import { aa as ensureI18nInitialized, al as detectConfigManagementMode, ab as i18n, ac as addNumbersToChoices, ai as readJsonConfig, l as CODEX_AUTH_FILE } from './simple-config.mjs';
4
+ import { deleteProviders, addProviderToExisting, editExistingProvider } from './codex-provider-manager.mjs';
5
5
  import 'node:fs';
6
6
  import 'node:process';
7
7
  import 'node:child_process';
@@ -33,6 +33,7 @@ async function configureIncrementalManagement() {
33
33
  const choices = [
34
34
  { name: i18n.t("codex:addProvider"), value: "add" },
35
35
  { name: i18n.t("codex:editProvider"), value: "edit" },
36
+ { name: i18n.t("codex:copyProvider"), value: "copy" },
36
37
  { name: i18n.t("codex:deleteProvider"), value: "delete" },
37
38
  { name: i18n.t("common:skip"), value: "skip" }
38
39
  ];
@@ -53,22 +54,50 @@ async function configureIncrementalManagement() {
53
54
  case "edit":
54
55
  await handleEditProvider(managementMode.providers);
55
56
  break;
57
+ case "copy":
58
+ await handleCopyProvider(managementMode.providers);
59
+ break;
56
60
  case "delete":
57
61
  await handleDeleteProvider(managementMode.providers);
58
62
  break;
59
63
  }
60
64
  }
61
65
  async function handleAddProvider() {
66
+ const { getApiProviders } = await import('./api-providers.mjs');
67
+ const apiProviders = getApiProviders("codex");
68
+ const providerChoices = [
69
+ { name: i18n.t("api:customProvider"), value: "custom" },
70
+ ...apiProviders.map((p) => ({ name: p.name, value: p.id }))
71
+ ];
72
+ const { selectedProvider } = await inquirer.prompt([{
73
+ type: "list",
74
+ name: "selectedProvider",
75
+ message: i18n.t("api:selectApiProvider"),
76
+ choices: addNumbersToChoices(providerChoices)
77
+ }]);
78
+ let prefilledBaseUrl;
79
+ let prefilledWireApi;
80
+ let prefilledModel;
81
+ if (selectedProvider !== "custom") {
82
+ const provider2 = apiProviders.find((p) => p.id === selectedProvider);
83
+ if (provider2?.codex) {
84
+ prefilledBaseUrl = provider2.codex.baseUrl;
85
+ prefilledWireApi = provider2.codex.wireApi;
86
+ prefilledModel = provider2.codex.defaultModel;
87
+ console.log(ansis.gray(i18n.t("api:providerSelected", { name: provider2.name })));
88
+ }
89
+ }
62
90
  const answers = await inquirer.prompt([
63
91
  {
64
92
  type: "input",
65
93
  name: "providerName",
66
94
  message: i18n.t("codex:providerNamePrompt"),
95
+ default: selectedProvider !== "custom" ? apiProviders.find((p) => p.id === selectedProvider)?.name : void 0,
67
96
  validate: (input) => {
68
97
  const trimmed = input.trim();
69
98
  if (!trimmed)
70
99
  return i18n.t("codex:providerNameRequired");
71
- if (!/^[\w\-\s]+$/.test(trimmed))
100
+ if (!/^[\w\-\s.]+$/.test(trimmed))
72
101
  return i18n.t("codex:providerNameInvalid");
73
102
  return true;
74
103
  }
@@ -77,7 +106,8 @@ async function handleAddProvider() {
77
106
  type: "input",
78
107
  name: "baseUrl",
79
108
  message: i18n.t("codex:providerBaseUrlPrompt"),
80
- default: "https://api.openai.com/v1",
109
+ default: prefilledBaseUrl || "https://api.openai.com/v1",
110
+ when: () => selectedProvider === "custom",
81
111
  validate: (input) => !!input.trim() || i18n.t("codex:providerBaseUrlRequired")
82
112
  },
83
113
  {
@@ -88,30 +118,63 @@ async function handleAddProvider() {
88
118
  { name: i18n.t("codex:protocolResponses"), value: "responses" },
89
119
  { name: i18n.t("codex:protocolChat"), value: "chat" }
90
120
  ],
91
- default: "responses"
121
+ default: prefilledWireApi || "responses",
122
+ when: () => selectedProvider === "custom"
92
123
  },
93
124
  {
94
125
  type: "input",
95
126
  name: "apiKey",
96
- message: i18n.t("codex:providerApiKeyPrompt"),
127
+ message: selectedProvider !== "custom" ? i18n.t("api:enterProviderApiKey", { provider: apiProviders.find((p) => p.id === selectedProvider)?.name || selectedProvider }) : i18n.t("codex:providerApiKeyPrompt"),
97
128
  validate: (input) => !!input.trim() || i18n.t("codex:providerApiKeyRequired")
98
129
  }
99
130
  ]);
100
- const providerId = answers.providerName.trim().toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9\-]/g, "");
131
+ const providerId = answers.providerName.trim().toLowerCase().replace(/\s+/g, "-").replace(/\./g, "-").replace(/[^a-z0-9\-]/g, "");
132
+ const managementMode = detectConfigManagementMode();
133
+ const existingProvider = managementMode.providers?.find((p) => p.id === providerId);
134
+ if (existingProvider) {
135
+ const { shouldOverwrite } = await inquirer.prompt([{
136
+ type: "confirm",
137
+ name: "shouldOverwrite",
138
+ message: i18n.t("codex:providerDuplicatePrompt", {
139
+ name: existingProvider.name,
140
+ source: i18n.t("codex:existingConfig")
141
+ }),
142
+ default: false
143
+ }]);
144
+ if (!shouldOverwrite) {
145
+ console.log(ansis.yellow(i18n.t("codex:providerDuplicateSkipped")));
146
+ return;
147
+ }
148
+ }
101
149
  const provider = {
102
150
  id: providerId,
103
151
  name: answers.providerName.trim(),
104
- baseUrl: answers.baseUrl.trim(),
105
- wireApi: answers.wireApi,
152
+ baseUrl: selectedProvider === "custom" ? answers.baseUrl.trim() : prefilledBaseUrl,
153
+ wireApi: selectedProvider === "custom" ? answers.wireApi : prefilledWireApi,
106
154
  envKey: `${providerId.toUpperCase().replace(/-/g, "_")}_API_KEY`,
107
- requiresOpenaiAuth: true
155
+ requiresOpenaiAuth: true,
156
+ model: prefilledModel || "gpt-5-codex"
157
+ // Use provider's default model or fallback
108
158
  };
109
- const result = await addProviderToExisting(provider, answers.apiKey.trim());
159
+ const result = await addProviderToExisting(provider, answers.apiKey.trim(), true);
110
160
  if (result.success) {
111
161
  console.log(ansis.green(i18n.t("codex:providerAdded", { name: result.addedProvider?.name })));
112
162
  if (result.backupPath) {
113
163
  console.log(ansis.gray(i18n.t("common:backupCreated", { path: result.backupPath })));
114
164
  }
165
+ const { setAsDefault } = await inquirer.prompt([{
166
+ type: "confirm",
167
+ name: "setAsDefault",
168
+ message: i18n.t("multi-config:setAsDefaultPrompt"),
169
+ default: true
170
+ }]);
171
+ if (setAsDefault) {
172
+ const { switchToProvider } = await import('./simple-config.mjs').then(function (n) { return n.bb; });
173
+ const switched = await switchToProvider(provider.id);
174
+ if (switched) {
175
+ console.log(ansis.green(i18n.t("multi-config:profileSetAsDefault", { name: provider.name })));
176
+ }
177
+ }
115
178
  } else {
116
179
  console.log(ansis.red(i18n.t("codex:providerAddFailed", { error: result.error })));
117
180
  }
@@ -136,6 +199,8 @@ async function handleEditProvider(providers) {
136
199
  console.log(ansis.red(i18n.t("codex:providerNotFound")));
137
200
  return;
138
201
  }
202
+ const existingAuth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
203
+ const existingApiKey = existingAuth[provider.envKey] || "";
139
204
  const answers = await inquirer.prompt([
140
205
  {
141
206
  type: "input",
@@ -172,14 +237,26 @@ async function handleEditProvider(providers) {
172
237
  type: "input",
173
238
  name: "apiKey",
174
239
  message: i18n.t("codex:providerApiKeyPrompt"),
240
+ default: existingApiKey,
241
+ // Show old API key from auth.json
175
242
  validate: (input) => !!input.trim() || i18n.t("codex:providerApiKeyRequired")
176
243
  }
177
244
  ]);
245
+ const { model } = await inquirer.prompt([
246
+ {
247
+ type: "input",
248
+ name: "model",
249
+ message: i18n.t("codex:providerModelPrompt"),
250
+ default: provider.model || "gpt-5-codex",
251
+ validate: (input) => !!input.trim() || i18n.t("codex:providerModelRequired")
252
+ }
253
+ ]);
178
254
  const updates = {
179
255
  name: answers.providerName.trim(),
180
256
  baseUrl: answers.baseUrl.trim(),
181
257
  wireApi: answers.wireApi,
182
- apiKey: answers.apiKey.trim()
258
+ apiKey: answers.apiKey.trim(),
259
+ model: model.trim()
183
260
  };
184
261
  const result = await editExistingProvider(selectedProviderId, updates);
185
262
  if (result.success) {
@@ -191,6 +268,114 @@ async function handleEditProvider(providers) {
191
268
  console.log(ansis.red(i18n.t("codex:providerUpdateFailed", { error: result.error })));
192
269
  }
193
270
  }
271
+ async function handleCopyProvider(providers) {
272
+ const choices = providers.map((provider2) => ({
273
+ name: `${provider2.name} (${provider2.baseUrl})`,
274
+ value: provider2.id
275
+ }));
276
+ const { selectedProviderId } = await inquirer.prompt([{
277
+ type: "list",
278
+ name: "selectedProviderId",
279
+ message: i18n.t("codex:selectProviderToCopy"),
280
+ choices: addNumbersToChoices(choices)
281
+ }]);
282
+ if (!selectedProviderId) {
283
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
284
+ return;
285
+ }
286
+ const provider = providers.find((p) => p.id === selectedProviderId);
287
+ if (!provider) {
288
+ console.log(ansis.red(i18n.t("codex:providerNotFound")));
289
+ return;
290
+ }
291
+ console.log(ansis.cyan(`
292
+ ${i18n.t("codex:copyingProvider", { name: provider.name })}`));
293
+ const existingAuth = readJsonConfig(CODEX_AUTH_FILE, { defaultValue: {} }) || {};
294
+ const existingApiKey = existingAuth[provider.envKey] || "";
295
+ const copiedName = `${provider.name}-copy`;
296
+ const answers = await inquirer.prompt([
297
+ {
298
+ type: "input",
299
+ name: "providerName",
300
+ message: i18n.t("codex:providerNamePrompt"),
301
+ default: copiedName,
302
+ validate: (input) => {
303
+ const trimmed = input.trim();
304
+ if (!trimmed)
305
+ return i18n.t("codex:providerNameRequired");
306
+ if (!/^[\w\-\s.]+$/.test(trimmed))
307
+ return i18n.t("codex:providerNameInvalid");
308
+ return true;
309
+ }
310
+ },
311
+ {
312
+ type: "input",
313
+ name: "baseUrl",
314
+ message: i18n.t("codex:providerBaseUrlPrompt"),
315
+ default: provider.baseUrl,
316
+ validate: (input) => !!input.trim() || i18n.t("codex:providerBaseUrlRequired")
317
+ },
318
+ {
319
+ type: "list",
320
+ name: "wireApi",
321
+ message: i18n.t("codex:providerProtocolPrompt"),
322
+ choices: [
323
+ { name: i18n.t("codex:protocolResponses"), value: "responses" },
324
+ { name: i18n.t("codex:protocolChat"), value: "chat" }
325
+ ],
326
+ default: provider.wireApi
327
+ },
328
+ {
329
+ type: "input",
330
+ name: "apiKey",
331
+ message: i18n.t("codex:providerApiKeyPrompt"),
332
+ default: existingApiKey,
333
+ // Show old API key from auth.json
334
+ validate: (input) => !!input.trim() || i18n.t("codex:providerApiKeyRequired")
335
+ }
336
+ ]);
337
+ const { model } = await inquirer.prompt([
338
+ {
339
+ type: "input",
340
+ name: "model",
341
+ message: i18n.t("codex:providerModelPrompt"),
342
+ default: provider.model || "gpt-5-codex",
343
+ validate: (input) => !!input.trim() || i18n.t("codex:providerModelRequired")
344
+ }
345
+ ]);
346
+ const providerId = answers.providerName.trim().toLowerCase().replace(/\s+/g, "-").replace(/\./g, "-").replace(/[^a-z0-9\-]/g, "");
347
+ const copiedProvider = {
348
+ id: providerId,
349
+ name: answers.providerName.trim(),
350
+ baseUrl: answers.baseUrl.trim(),
351
+ wireApi: answers.wireApi,
352
+ envKey: `${providerId.toUpperCase().replace(/-/g, "_")}_API_KEY`,
353
+ requiresOpenaiAuth: provider.requiresOpenaiAuth ?? true,
354
+ model: model.trim()
355
+ };
356
+ const result = await addProviderToExisting(copiedProvider, answers.apiKey.trim(), false);
357
+ if (result.success) {
358
+ console.log(ansis.green(i18n.t("codex:providerCopied", { name: result.addedProvider?.name })));
359
+ if (result.backupPath) {
360
+ console.log(ansis.gray(i18n.t("common:backupCreated", { path: result.backupPath })));
361
+ }
362
+ const { setAsDefault } = await inquirer.prompt([{
363
+ type: "confirm",
364
+ name: "setAsDefault",
365
+ message: i18n.t("multi-config:setAsDefaultPrompt"),
366
+ default: false
367
+ }]);
368
+ if (setAsDefault) {
369
+ const { switchToProvider } = await import('./simple-config.mjs').then(function (n) { return n.bb; });
370
+ const switched = await switchToProvider(copiedProvider.id);
371
+ if (switched) {
372
+ console.log(ansis.green(i18n.t("multi-config:profileSetAsDefault", { name: copiedProvider.name })));
373
+ }
374
+ }
375
+ } else {
376
+ console.log(ansis.red(i18n.t("codex:providerCopyFailed", { error: result.error })));
377
+ }
378
+ }
194
379
  async function handleDeleteProvider(providers) {
195
380
  const choices = providers.map((provider) => ({
196
381
  name: `${provider.name} (${provider.baseUrl})`,
@@ -1,4 +1,4 @@
1
- import { ag as readCodexConfig, ah as backupCodexComplete, ai as writeCodexConfig, aj as writeAuthFile } from './simple-config.mjs';
1
+ import { am as readCodexConfig, an as backupCodexComplete, ao as writeCodexConfig, ap as writeAuthFile } from './simple-config.mjs';
2
2
  import 'node:fs';
3
3
  import 'node:process';
4
4
  import 'ansis';
@@ -26,7 +26,7 @@ const ERROR_MESSAGES = {
26
26
  PROVIDERS_NOT_FOUND: (providers) => `Some providers not found: ${providers.join(", ")}`,
27
27
  CANNOT_DELETE_ALL: "Cannot delete all providers. At least one provider must remain."
28
28
  };
29
- async function addProviderToExisting(provider, apiKey) {
29
+ async function addProviderToExisting(provider, apiKey, allowOverwrite = false) {
30
30
  try {
31
31
  const existingConfig = readCodexConfig();
32
32
  if (!existingConfig) {
@@ -35,8 +35,8 @@ async function addProviderToExisting(provider, apiKey) {
35
35
  error: ERROR_MESSAGES.NO_CONFIG
36
36
  };
37
37
  }
38
- const existingProvider = existingConfig.providers.find((p) => p.id === provider.id);
39
- if (existingProvider) {
38
+ const existingProviderIndex = existingConfig.providers.findIndex((p) => p.id === provider.id);
39
+ if (existingProviderIndex !== -1 && !allowOverwrite) {
40
40
  return {
41
41
  success: false,
42
42
  error: ERROR_MESSAGES.PROVIDER_EXISTS(provider.id)
@@ -49,10 +49,20 @@ async function addProviderToExisting(provider, apiKey) {
49
49
  error: ERROR_MESSAGES.BACKUP_FAILED
50
50
  };
51
51
  }
52
- const updatedConfig = {
53
- ...existingConfig,
54
- providers: [...existingConfig.providers, provider]
55
- };
52
+ let updatedConfig;
53
+ if (existingProviderIndex !== -1) {
54
+ const updatedProviders = [...existingConfig.providers];
55
+ updatedProviders[existingProviderIndex] = provider;
56
+ updatedConfig = {
57
+ ...existingConfig,
58
+ providers: updatedProviders
59
+ };
60
+ } else {
61
+ updatedConfig = {
62
+ ...existingConfig,
63
+ providers: [...existingConfig.providers, provider]
64
+ };
65
+ }
56
66
  writeCodexConfig(updatedConfig);
57
67
  const authEntries = {};
58
68
  authEntries[provider.envKey] = apiKey;
@@ -96,7 +106,8 @@ async function editExistingProvider(providerId, updates) {
96
106
  ...existingConfig.providers[providerIndex],
97
107
  ...updates.name && { name: updates.name },
98
108
  ...updates.baseUrl && { baseUrl: updates.baseUrl },
99
- ...updates.wireApi && { wireApi: updates.wireApi }
109
+ ...updates.wireApi && { wireApi: updates.wireApi },
110
+ ...updates.model && { model: updates.model }
100
111
  };
101
112
  const updatedProviders = [...existingConfig.providers];
102
113
  updatedProviders[providerIndex] = updatedProvider;
@@ -1,14 +1,14 @@
1
- import { homedir } from 'node:os';
2
1
  import { pathExists } from 'fs-extra';
3
2
  import { join } from 'pathe';
4
3
  import { exec } from 'tinyexec';
5
- import { a5 as i18n } from './simple-config.mjs';
4
+ import { j as CODEX_DIR, k as CODEX_CONFIG_FILE, ab as i18n, l as CODEX_AUTH_FILE, n as CODEX_AGENTS_FILE, p as CODEX_PROMPTS_DIR } from './simple-config.mjs';
6
5
  import { m as moveToTrash } from '../shared/zcf.DGjQxTq_.mjs';
7
6
  import 'node:fs';
8
7
  import 'node:process';
9
8
  import 'ansis';
10
9
  import 'inquirer';
11
10
  import 'node:child_process';
11
+ import 'node:os';
12
12
  import 'node:util';
13
13
  import 'dayjs';
14
14
  import 'node:url';
@@ -23,12 +23,7 @@ import 'trash';
23
23
  class CodexUninstaller {
24
24
  _lang;
25
25
  conflictResolution = /* @__PURE__ */ new Map();
26
- CODEX_DIR = join(homedir(), ".codex");
27
- CODEX_CONFIG_FILE = join(this.CODEX_DIR, "config.toml");
28
- CODEX_AUTH_FILE = join(this.CODEX_DIR, "auth.json");
29
- CODEX_AGENTS_FILE = join(this.CODEX_DIR, "AGENTS.md");
30
- CODEX_PROMPTS_DIR = join(this.CODEX_DIR, "prompts");
31
- CODEX_BACKUP_DIR = join(this.CODEX_DIR, "backup");
26
+ CODEX_BACKUP_DIR = join(CODEX_DIR, "backup");
32
27
  constructor(lang = "en") {
33
28
  this._lang = lang;
34
29
  this.conflictResolution.set("cli-package", ["config", "auth"]);
@@ -47,8 +42,8 @@ class CodexUninstaller {
47
42
  warnings: []
48
43
  };
49
44
  try {
50
- if (await pathExists(this.CODEX_CONFIG_FILE)) {
51
- const trashResult = await moveToTrash(this.CODEX_CONFIG_FILE);
45
+ if (await pathExists(CODEX_CONFIG_FILE)) {
46
+ const trashResult = await moveToTrash(CODEX_CONFIG_FILE);
52
47
  if (!trashResult[0]?.success) {
53
48
  result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
54
49
  }
@@ -75,8 +70,8 @@ class CodexUninstaller {
75
70
  warnings: []
76
71
  };
77
72
  try {
78
- if (await pathExists(this.CODEX_AUTH_FILE)) {
79
- const trashResult = await moveToTrash(this.CODEX_AUTH_FILE);
73
+ if (await pathExists(CODEX_AUTH_FILE)) {
74
+ const trashResult = await moveToTrash(CODEX_AUTH_FILE);
80
75
  if (!trashResult[0]?.success) {
81
76
  result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
82
77
  }
@@ -103,8 +98,8 @@ class CodexUninstaller {
103
98
  warnings: []
104
99
  };
105
100
  try {
106
- if (await pathExists(this.CODEX_AGENTS_FILE)) {
107
- const trashResult = await moveToTrash(this.CODEX_AGENTS_FILE);
101
+ if (await pathExists(CODEX_AGENTS_FILE)) {
102
+ const trashResult = await moveToTrash(CODEX_AGENTS_FILE);
108
103
  if (!trashResult[0]?.success) {
109
104
  result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
110
105
  }
@@ -131,8 +126,8 @@ class CodexUninstaller {
131
126
  warnings: []
132
127
  };
133
128
  try {
134
- if (await pathExists(this.CODEX_PROMPTS_DIR)) {
135
- const trashResult = await moveToTrash(this.CODEX_PROMPTS_DIR);
129
+ if (await pathExists(CODEX_PROMPTS_DIR)) {
130
+ const trashResult = await moveToTrash(CODEX_PROMPTS_DIR);
136
131
  if (!trashResult[0]?.success) {
137
132
  result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
138
133
  }
@@ -184,9 +179,9 @@ class CodexUninstaller {
184
179
  warnings: []
185
180
  };
186
181
  try {
187
- if (await pathExists(this.CODEX_CONFIG_FILE)) {
182
+ if (await pathExists(CODEX_CONFIG_FILE)) {
188
183
  const { readFileSync, writeFileSync } = await import('node:fs');
189
- const content = readFileSync(this.CODEX_CONFIG_FILE, "utf-8");
184
+ const content = readFileSync(CODEX_CONFIG_FILE, "utf-8");
190
185
  const lines = content.split("\n");
191
186
  const newLines = [];
192
187
  let inProviderSection = false;
@@ -210,7 +205,7 @@ class CodexUninstaller {
210
205
  newLines.push(line);
211
206
  }
212
207
  if (configModified) {
213
- writeFileSync(this.CODEX_CONFIG_FILE, newLines.join("\n"));
208
+ writeFileSync(CODEX_CONFIG_FILE, newLines.join("\n"));
214
209
  result.removedConfigs.push(i18n.t("codex:apiConfigRemoved"));
215
210
  }
216
211
  result.success = true;
@@ -263,9 +258,9 @@ class CodexUninstaller {
263
258
  warnings: []
264
259
  };
265
260
  try {
266
- if (await pathExists(this.CODEX_CONFIG_FILE)) {
261
+ if (await pathExists(CODEX_CONFIG_FILE)) {
267
262
  const { readFileSync, writeFileSync } = await import('node:fs');
268
- const content = readFileSync(this.CODEX_CONFIG_FILE, "utf-8");
263
+ const content = readFileSync(CODEX_CONFIG_FILE, "utf-8");
269
264
  const lines = content.split("\n");
270
265
  const newLines = [];
271
266
  let inMcpSection = false;
@@ -285,7 +280,7 @@ class CodexUninstaller {
285
280
  newLines.push(line);
286
281
  }
287
282
  if (configModified) {
288
- writeFileSync(this.CODEX_CONFIG_FILE, newLines.join("\n"));
283
+ writeFileSync(CODEX_CONFIG_FILE, newLines.join("\n"));
289
284
  result.removedConfigs.push(i18n.t("codex:mcpConfigRemoved"));
290
285
  }
291
286
  result.success = true;
@@ -310,8 +305,8 @@ class CodexUninstaller {
310
305
  warnings: []
311
306
  };
312
307
  try {
313
- if (await pathExists(this.CODEX_DIR)) {
314
- const trashResult = await moveToTrash(this.CODEX_DIR);
308
+ if (await pathExists(CODEX_DIR)) {
309
+ const trashResult = await moveToTrash(CODEX_DIR);
315
310
  if (!trashResult[0]?.success) {
316
311
  result.warnings.push(`Failed to move ~/.codex/ to trash: ${trashResult[0]?.error || "Unknown error"}`);
317
312
  }
@@ -1,7 +1,7 @@
1
1
  import { exec } from 'node:child_process';
2
2
  import { promisify } from 'node:util';
3
3
  import ansis from 'ansis';
4
- import { a4 as ensureI18nInitialized, a5 as i18n } from './simple-config.mjs';
4
+ import { aa as ensureI18nInitialized, ab as i18n } from './simple-config.mjs';
5
5
  import 'node:fs';
6
6
  import 'node:process';
7
7
  import 'inquirer';