theclawbay 0.3.71 → 0.3.73

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.
@@ -11,5 +11,3 @@ export type SupportedModelConfig = {
11
11
  export declare function getSupportedModels(): SupportedModelConfig[];
12
12
  export declare function getSupportedModelIds(): string[];
13
13
  export declare function getSupportedModelDisplayNames(): Record<string, string>;
14
- export declare function getLegacyRemovedModelIds(): string[];
15
- export declare function getKnownTheClawBayModelIds(): string[];
@@ -6,19 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getSupportedModels = getSupportedModels;
7
7
  exports.getSupportedModelIds = getSupportedModelIds;
8
8
  exports.getSupportedModelDisplayNames = getSupportedModelDisplayNames;
9
- exports.getLegacyRemovedModelIds = getLegacyRemovedModelIds;
10
- exports.getKnownTheClawBayModelIds = getKnownTheClawBayModelIds;
11
9
  const node_path_1 = __importDefault(require("node:path"));
12
10
  const node_fs_1 = require("node:fs");
13
11
  function configPath() {
14
12
  return node_path_1.default.resolve(__dirname, "..", "..", "theclawbay-supported-models.json");
15
13
  }
16
- const LEGACY_REMOVED_MODEL_IDS = [
17
- "gpt-image-1.5",
18
- "gpt-5.2-codex",
19
- "gpt-5.1-codex-max",
20
- "gpt-5.1-codex-mini",
21
- ];
22
14
  function parseSupportedModels(raw) {
23
15
  const parsed = JSON.parse(raw);
24
16
  if (!Array.isArray(parsed)) {
@@ -69,9 +61,3 @@ function getSupportedModelIds() {
69
61
  function getSupportedModelDisplayNames() {
70
62
  return Object.fromEntries(getSupportedModels().map((model) => [model.id, model.label]));
71
63
  }
72
- function getLegacyRemovedModelIds() {
73
- return [...LEGACY_REMOVED_MODEL_IDS];
74
- }
75
- function getKnownTheClawBayModelIds() {
76
- return Array.from(new Set([...getSupportedModelIds(), ...getLegacyRemovedModelIds()]));
77
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "theclawbay",
3
- "version": "0.3.71",
3
+ "version": "0.3.73",
4
4
  "description": "CLI for connecting Codex, Continue, Cline, GSD, OpenClaw, OpenCode, Kilo, Roo Code, Aider, experimental Trae, and experimental Zo to The Claw Bay.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,7 +27,6 @@
27
27
  },
28
28
  "files": [
29
29
  "dist",
30
- "theclawbay-codex-model-catalog.json",
31
30
  "theclawbay-supported-models.json",
32
31
  "README.md",
33
32
  "LICENSE"
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "id": "gpt-5.5",
4
4
  "label": "GPT-5.5",
5
- "note": "Newest Codex model for stronger coding and agentic work.",
5
+ "note": "Frontier model for complex coding, research, and real-world work.",
6
6
  "tone": "coral",
7
7
  "inputPer1M": 5.0,
8
8
  "cachedInputPer1M": 0.5,
@@ -26,6 +26,24 @@
26
26
  "cachedInputPer1M": 0.125,
27
27
  "outputPer1M": 10.0
28
28
  },
29
+ {
30
+ "id": "gpt-image-2",
31
+ "label": "GPT Image 2",
32
+ "note": "OpenAI-compatible image generation endpoint backed by codex-lb.",
33
+ "tone": "coral",
34
+ "inputPer1M": 5.0,
35
+ "cachedInputPer1M": 2.0,
36
+ "outputPer1M": 30.0
37
+ },
38
+ {
39
+ "id": "gpt-image-1.5",
40
+ "label": "GPT Image 1.5",
41
+ "note": "Native image generation model for direct image outputs.",
42
+ "tone": "coral",
43
+ "inputPer1M": 8.0,
44
+ "cachedInputPer1M": 2.0,
45
+ "outputPer1M": 32.0
46
+ },
29
47
  {
30
48
  "id": "gpt-5.3-codex",
31
49
  "label": "GPT-5.3 Codex",
@@ -35,6 +53,15 @@
35
53
  "cachedInputPer1M": 0.175,
36
54
  "outputPer1M": 14.0
37
55
  },
56
+ {
57
+ "id": "gpt-5.2-codex",
58
+ "label": "GPT-5.2 Codex",
59
+ "note": "Stable compatibility option for older Codex flows.",
60
+ "tone": "sea",
61
+ "inputPer1M": 1.75,
62
+ "cachedInputPer1M": 0.175,
63
+ "outputPer1M": 14.0
64
+ },
38
65
  {
39
66
  "id": "gpt-5.2",
40
67
  "label": "GPT-5.2",
@@ -43,5 +70,23 @@
43
70
  "inputPer1M": 1.75,
44
71
  "cachedInputPer1M": 0.175,
45
72
  "outputPer1M": 14.0
73
+ },
74
+ {
75
+ "id": "gpt-5.1-codex-max",
76
+ "label": "GPT-5.1 Codex Max",
77
+ "note": "Higher-throughput option for longer coding sessions.",
78
+ "tone": "coral",
79
+ "inputPer1M": 1.25,
80
+ "cachedInputPer1M": 0.125,
81
+ "outputPer1M": 10.0
82
+ },
83
+ {
84
+ "id": "gpt-5.1-codex-mini",
85
+ "label": "GPT-5.1 Codex Mini",
86
+ "note": "Lower-cost Codex path for quick iterations.",
87
+ "tone": "sea",
88
+ "inputPer1M": 0.25,
89
+ "cachedInputPer1M": 0.025,
90
+ "outputPer1M": 2.0
46
91
  }
47
92
  ]
@@ -1,7 +0,0 @@
1
- export type EnsureCodexDesktopModelPickerResult = {
2
- action: "patched" | "already_patched" | "skipped";
3
- warning?: string;
4
- patchedBundles: number;
5
- patchedCaches: number;
6
- };
7
- export declare function ensureCodexDesktopModelPickerSupport(): Promise<EnsureCodexDesktopModelPickerResult>;
@@ -1,452 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ensureCodexDesktopModelPickerSupport = ensureCodexDesktopModelPickerSupport;
7
- const node_child_process_1 = require("node:child_process");
8
- const promises_1 = __importDefault(require("node:fs/promises"));
9
- const node_os_1 = __importDefault(require("node:os"));
10
- const node_path_1 = __importDefault(require("node:path"));
11
- const paths_1 = require("./config/paths");
12
- const codex_model_catalog_1 = require("./codex-model-catalog");
13
- const DESKTOP_MODEL_IDS = Array.from(new Set((0, codex_model_catalog_1.getVisibleHardcodedCodexModelIds)()));
14
- const STATSIG_MODEL_PICKER_CONFIG_ID = "107580212";
15
- function uniqueStrings(values) {
16
- return Array.from(new Set(values.filter((value) => Boolean(value))));
17
- }
18
- async function pathExists(filePath) {
19
- try {
20
- await promises_1.default.access(filePath);
21
- return true;
22
- }
23
- catch {
24
- return false;
25
- }
26
- }
27
- function isWslInteropRuntime() {
28
- return node_os_1.default.platform() === "linux" && Boolean(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP);
29
- }
30
- function readWindowsCommandStdout(command) {
31
- const shell = node_os_1.default.platform() === "win32" ? "powershell.exe" : isWslInteropRuntime() ? "powershell.exe" : null;
32
- if (!shell)
33
- return null;
34
- const result = (0, node_child_process_1.spawnSync)(shell, ["-NoProfile", "-Command", command], {
35
- encoding: "utf8",
36
- stdio: ["ignore", "pipe", "ignore"],
37
- });
38
- if (result.status !== 0)
39
- return null;
40
- const output = result.stdout.replace(/\r/g, "").trim();
41
- return output || null;
42
- }
43
- function desktopClientsLikelyRunning() {
44
- if (node_os_1.default.platform() === "win32" || isWslInteropRuntime()) {
45
- const running = readWindowsCommandStdout("Get-Process Code,Codex -ErrorAction SilentlyContinue | Select-Object -ExpandProperty ProcessName");
46
- return Boolean(running);
47
- }
48
- const result = (0, node_child_process_1.spawnSync)("sh", ["-lc", "pgrep -if '(^|/)(code|codex)$' >/dev/null"], {
49
- stdio: "ignore",
50
- });
51
- return result.status === 0;
52
- }
53
- function resolveWindowsPathForHost(input) {
54
- if (!input)
55
- return null;
56
- const trimmed = input.trim();
57
- if (!trimmed)
58
- return null;
59
- if (node_os_1.default.platform() === "win32")
60
- return trimmed;
61
- const match = /^([A-Za-z]):\\(.*)$/.exec(trimmed);
62
- if (!match)
63
- return null;
64
- return node_path_1.default.posix.join("/mnt", match[1].toLowerCase(), match[2].replace(/\\/g, "/"));
65
- }
66
- function resolveWindowsHomeDirForHost() {
67
- const reported = readWindowsCommandStdout("$env:USERPROFILE");
68
- if (reported)
69
- return resolveWindowsPathForHost(reported);
70
- return node_os_1.default.platform() === "win32" ? node_os_1.default.homedir() : null;
71
- }
72
- function editorExtensionDirCandidates() {
73
- const home = node_os_1.default.homedir();
74
- const dirs = [];
75
- if (node_os_1.default.platform() === "darwin") {
76
- return uniqueStrings([
77
- node_path_1.default.join(home, ".vscode", "extensions"),
78
- node_path_1.default.join(home, ".vscode-insiders", "extensions"),
79
- node_path_1.default.join(home, ".vscode-oss", "extensions"),
80
- ]);
81
- }
82
- if (node_os_1.default.platform() === "win32") {
83
- const homeDir = process.env.USERPROFILE?.trim() || home;
84
- return uniqueStrings([
85
- node_path_1.default.join(homeDir, ".vscode", "extensions"),
86
- node_path_1.default.join(homeDir, ".vscode-insiders", "extensions"),
87
- node_path_1.default.join(homeDir, ".vscode-oss", "extensions"),
88
- ]);
89
- }
90
- dirs.push(node_path_1.default.join(home, ".vscode", "extensions"), node_path_1.default.join(home, ".vscode-insiders", "extensions"), node_path_1.default.join(home, ".vscode-oss", "extensions"));
91
- if (isWslInteropRuntime()) {
92
- const windowsHome = resolveWindowsHomeDirForHost();
93
- if (windowsHome) {
94
- dirs.push(node_path_1.default.join(windowsHome, ".vscode", "extensions"), node_path_1.default.join(windowsHome, ".vscode-insiders", "extensions"), node_path_1.default.join(windowsHome, ".vscode-oss", "extensions"));
95
- }
96
- }
97
- return uniqueStrings(dirs);
98
- }
99
- async function findWritableCodexWebviewBundleFiles() {
100
- const results = [];
101
- for (const extensionDir of editorExtensionDirCandidates()) {
102
- let entries = [];
103
- try {
104
- entries = await promises_1.default.readdir(extensionDir, { withFileTypes: true });
105
- }
106
- catch (error) {
107
- const err = error;
108
- if (err.code === "ENOENT")
109
- continue;
110
- throw error;
111
- }
112
- for (const entry of entries) {
113
- if (!entry.isDirectory())
114
- continue;
115
- if (!entry.name.toLowerCase().startsWith("openai.chatgpt-"))
116
- continue;
117
- const assetsDir = node_path_1.default.join(extensionDir, entry.name, "webview", "assets");
118
- let assetEntries = [];
119
- try {
120
- assetEntries = await promises_1.default.readdir(assetsDir, { withFileTypes: true });
121
- }
122
- catch (error) {
123
- const err = error;
124
- if (err.code === "ENOENT")
125
- continue;
126
- throw error;
127
- }
128
- for (const assetEntry of assetEntries) {
129
- if (!assetEntry.isFile())
130
- continue;
131
- if (!assetEntry.name.endsWith(".js"))
132
- continue;
133
- if (!assetEntry.name.startsWith("font-settings-") && !assetEntry.name.startsWith("index-"))
134
- continue;
135
- const filePath = node_path_1.default.join(assetsDir, assetEntry.name);
136
- try {
137
- await promises_1.default.access(filePath, 2);
138
- results.push(filePath);
139
- }
140
- catch {
141
- continue;
142
- }
143
- }
144
- }
145
- }
146
- return uniqueStrings(results);
147
- }
148
- function patchDesktopIndexBundle(source) {
149
- return source.replace(/let (\w+)=([\w$.]+)\.email\?\?void 0,(\w+)=\2\.userId\?\?void 0,(\w+)=(\w+)\?\?void 0,(\w+)=(\w+)\?\?void 0,(\w+);/g, "let $1=$2.email??void 0,$3=$2.userId??$7??$5??void 0,$4=$5??void 0,$6=$7??void 0,$8;");
150
- }
151
- function patchDesktopFontSettingsBundle(source) {
152
- return source.replace(/if\((\w+)\.useHiddenModels\?\1\.availableModels\.has\((\w+)\.model\):!\2\.hidden\)\{/g, "if(!$2.hidden||$1.availableModels.has($2.model)){");
153
- }
154
- async function patchCodexWebviewBundles() {
155
- const bundleFiles = await findWritableCodexWebviewBundleFiles();
156
- let patched = 0;
157
- for (const filePath of bundleFiles) {
158
- const original = await promises_1.default.readFile(filePath, "utf8");
159
- const next = filePath.includes(`${node_path_1.default.sep}font-settings-`)
160
- ? patchDesktopFontSettingsBundle(original)
161
- : patchDesktopIndexBundle(original);
162
- if (next === original)
163
- continue;
164
- await promises_1.default.writeFile(filePath, next, "utf8");
165
- patched += 1;
166
- }
167
- return { patched, scanned: bundleFiles.length };
168
- }
169
- function resolvePythonCommand() {
170
- const candidates = [
171
- { command: "python3", args: [] },
172
- { command: "python", args: [] },
173
- { command: "py", args: ["-3"] },
174
- ];
175
- for (const candidate of candidates) {
176
- const result = (0, node_child_process_1.spawnSync)(candidate.command, [...candidate.args, "-c", "import sys; print(sys.version)"], {
177
- encoding: "utf8",
178
- stdio: ["ignore", "pipe", "ignore"],
179
- });
180
- if (result.status === 0)
181
- return candidate;
182
- }
183
- return null;
184
- }
185
- function venvPythonPath(venvDir) {
186
- if (node_os_1.default.platform() === "win32") {
187
- return node_path_1.default.join(venvDir, "Scripts", "python.exe");
188
- }
189
- return node_path_1.default.join(venvDir, "bin", "python");
190
- }
191
- function runPython(command, script, extraArgs = []) {
192
- return (0, node_child_process_1.spawnSync)(command.command, [...command.args, "-c", script, ...extraArgs], {
193
- encoding: "utf8",
194
- stdio: ["ignore", "pipe", "pipe"],
195
- });
196
- }
197
- function pythonImportsLevelDb(command) {
198
- const result = runPython(command, "import plyvel");
199
- return result.status === 0;
200
- }
201
- async function ensureLocalPythonWithLevelDbSupport() {
202
- const systemPython = resolvePythonCommand();
203
- if (!systemPython)
204
- return null;
205
- if (pythonImportsLevelDb(systemPython))
206
- return systemPython;
207
- const venvDir = node_path_1.default.join(paths_1.theclawbayStateDir, "python", "leveldb");
208
- const venvPython = venvPythonPath(venvDir);
209
- const venvCommand = { command: venvPython, args: [] };
210
- const existingVenv = (0, node_child_process_1.spawnSync)(venvPython, ["-c", "import sys; print(sys.executable)"], {
211
- stdio: "ignore",
212
- });
213
- if (existingVenv.status !== 0) {
214
- await promises_1.default.mkdir(node_path_1.default.dirname(venvDir), { recursive: true });
215
- const createVenv = (0, node_child_process_1.spawnSync)(systemPython.command, [...systemPython.args, "-m", "venv", venvDir], {
216
- encoding: "utf8",
217
- stdio: ["ignore", "pipe", "pipe"],
218
- });
219
- if (createVenv.status !== 0)
220
- return null;
221
- }
222
- if (!pythonImportsLevelDb(venvCommand)) {
223
- const pipArgs = ["-m", "pip", "install", "--disable-pip-version-check", "plyvel-ci"];
224
- let install = (0, node_child_process_1.spawnSync)(venvPython, pipArgs, {
225
- encoding: "utf8",
226
- stdio: ["ignore", "pipe", "pipe"],
227
- });
228
- if (install.status !== 0) {
229
- install = (0, node_child_process_1.spawnSync)(venvPython, ["-m", "pip", "install", "--disable-pip-version-check", "plyvel"], {
230
- encoding: "utf8",
231
- stdio: ["ignore", "pipe", "pipe"],
232
- });
233
- if (install.status !== 0)
234
- return null;
235
- }
236
- }
237
- return pythonImportsLevelDb(venvCommand) ? venvCommand : null;
238
- }
239
- async function findWindowsCodexPackageLevelDbDirs(windowsHome) {
240
- const packagesRoot = node_path_1.default.join(windowsHome, "AppData", "Local", "Packages");
241
- let entries = [];
242
- try {
243
- entries = await promises_1.default.readdir(packagesRoot, { withFileTypes: true });
244
- }
245
- catch (error) {
246
- const err = error;
247
- if (err.code === "ENOENT")
248
- return [];
249
- throw error;
250
- }
251
- return uniqueStrings(entries
252
- .filter((entry) => entry.isDirectory() && entry.name.startsWith("OpenAI.Codex_"))
253
- .map((entry) => node_path_1.default.join(packagesRoot, entry.name, "LocalCache", "Roaming", "Codex", "Local Storage", "leveldb")));
254
- }
255
- async function desktopStatsigLevelDbCandidates() {
256
- const home = node_os_1.default.homedir();
257
- const candidates = [];
258
- if (node_os_1.default.platform() === "darwin") {
259
- candidates.push(node_path_1.default.join(home, "Library", "Application Support", "Code", "Local Storage", "leveldb"), node_path_1.default.join(home, "Library", "Application Support", "Code - Insiders", "Local Storage", "leveldb"), node_path_1.default.join(home, "Library", "Application Support", "Codex", "Local Storage", "leveldb"), node_path_1.default.join(home, "Library", "Containers", "OpenAI.Codex", "Data", "Library", "Application Support", "Codex", "Local Storage", "leveldb"));
260
- }
261
- else if (node_os_1.default.platform() === "win32") {
262
- const homeDir = process.env.USERPROFILE?.trim() || home;
263
- candidates.push(node_path_1.default.join(homeDir, "AppData", "Roaming", "Code", "Local Storage", "leveldb"), node_path_1.default.join(homeDir, "AppData", "Roaming", "Code - Insiders", "Local Storage", "leveldb"));
264
- candidates.push(...(await findWindowsCodexPackageLevelDbDirs(homeDir)));
265
- }
266
- else {
267
- candidates.push(node_path_1.default.join(home, ".config", "Code", "Local Storage", "leveldb"), node_path_1.default.join(home, ".config", "Code - Insiders", "Local Storage", "leveldb"), node_path_1.default.join(home, ".config", "Codex", "Local Storage", "leveldb"));
268
- if (isWslInteropRuntime()) {
269
- const windowsHome = resolveWindowsHomeDirForHost();
270
- if (windowsHome) {
271
- candidates.push(node_path_1.default.join(windowsHome, "AppData", "Roaming", "Code", "Local Storage", "leveldb"), node_path_1.default.join(windowsHome, "AppData", "Roaming", "Code - Insiders", "Local Storage", "leveldb"));
272
- candidates.push(...(await findWindowsCodexPackageLevelDbDirs(windowsHome)));
273
- }
274
- }
275
- }
276
- const existing = [];
277
- for (const candidate of uniqueStrings(candidates)) {
278
- if (await pathExists(candidate))
279
- existing.push(candidate);
280
- }
281
- return existing;
282
- }
283
- function buildStatsigPatchScript() {
284
- return [
285
- "import json, sys",
286
- "import plyvel",
287
- "target_models = json.loads(sys.argv[1])",
288
- `config_id = ${JSON.stringify(STATSIG_MODEL_PICKER_CONFIG_ID)}`,
289
- "for db_path in sys.argv[2:]:",
290
- " result = {'db': db_path, 'patched': 0, 'error': None}",
291
- " try:",
292
- " db = plyvel.DB(db_path, create_if_missing=False)",
293
- " except Exception as exc:",
294
- " result['error'] = str(exc)",
295
- " print(json.dumps(result))",
296
- " continue",
297
- " try:",
298
- " for key, raw in db:",
299
- " if b'statsig.cached.evaluations.' not in key:",
300
- " continue",
301
- " try:",
302
- " text = raw.decode('utf-8')",
303
- " prefix = '\\x01' if text.startswith('\\x01') else ''",
304
- " if prefix:",
305
- " text = text[1:]",
306
- " outer = json.loads(text)",
307
- " inner = json.loads(outer.get('data', '{}'))",
308
- " dynamic_configs = inner.get('dynamic_configs')",
309
- " if not isinstance(dynamic_configs, dict):",
310
- " continue",
311
- " config = dynamic_configs.get(config_id)",
312
- " if not isinstance(config, dict):",
313
- " continue",
314
- " value = config.get('value')",
315
- " if not isinstance(value, dict):",
316
- " continue",
317
- " current_models = value.get('available_models')",
318
- " merged = []",
319
- " seen = set()",
320
- " for model_id in list(target_models) + (current_models if isinstance(current_models, list) else []):",
321
- " if not isinstance(model_id, str):",
322
- " continue",
323
- " normalized = model_id.strip()",
324
- " if not normalized or normalized in seen:",
325
- " continue",
326
- " seen.add(normalized)",
327
- " merged.append(normalized)",
328
- " changed = False",
329
- " if value.get('use_hidden_models') is not False:",
330
- " value['use_hidden_models'] = False",
331
- " changed = True",
332
- " if value.get('available_models') != merged:",
333
- " value['available_models'] = merged",
334
- " changed = True",
335
- " if not changed:",
336
- " continue",
337
- " outer['data'] = json.dumps(inner, separators=(',', ':'))",
338
- " encoded = (prefix + json.dumps(outer, separators=(',', ':'))).encode('utf-8')",
339
- " db.put(key, encoded)",
340
- " result['patched'] += 1",
341
- " except Exception:",
342
- " continue",
343
- " finally:",
344
- " db.close()",
345
- " print(json.dumps(result))",
346
- ].join("\n");
347
- }
348
- function patchStatsigCache(python, dbDir) {
349
- const run = (0, node_child_process_1.spawnSync)(python.command, [...python.args, "-c", buildStatsigPatchScript(), JSON.stringify(DESKTOP_MODEL_IDS), dbDir], {
350
- encoding: "utf8",
351
- stdio: ["ignore", "pipe", "pipe"],
352
- });
353
- if (run.status !== 0) {
354
- const detail = (run.stderr || run.stdout || "").trim();
355
- return {
356
- patched: 0,
357
- warning: detail ? `${dbDir}: ${detail}` : `${dbDir}: desktop cache helper exited with status ${run.status}`,
358
- };
359
- }
360
- let patched = 0;
361
- const warnings = [];
362
- const lines = (run.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
363
- for (const line of lines) {
364
- try {
365
- const parsed = JSON.parse(line);
366
- patched += typeof parsed.patched === "number" ? parsed.patched : 0;
367
- if (typeof parsed.error === "string" && parsed.error.trim()) {
368
- const dbLabel = typeof parsed.db === "string" ? parsed.db : dbDir;
369
- warnings.push(`${dbLabel}: ${parsed.error.trim()}`);
370
- }
371
- }
372
- catch {
373
- continue;
374
- }
375
- }
376
- return { patched, warning: warnings.length > 0 ? warnings.join(" ") : undefined };
377
- }
378
- async function patchDesktopStatsigCaches() {
379
- const dbDirs = await desktopStatsigLevelDbCandidates();
380
- if (dbDirs.length === 0)
381
- return { patched: 0, warnings: [] };
382
- const python = await ensureLocalPythonWithLevelDbSupport();
383
- if (!python) {
384
- return {
385
- patched: 0,
386
- warnings: [
387
- "Could not install the local desktop model-picker helper, so Codex app model labels may stay stale until the next supported cache refresh.",
388
- ],
389
- };
390
- }
391
- let patched = 0;
392
- const warnings = [];
393
- for (const dbDir of dbDirs) {
394
- const result = patchStatsigCache(python, dbDir);
395
- patched += result.patched;
396
- if (result.warning)
397
- warnings.push(result.warning);
398
- }
399
- if (patched === 0 && warnings.length > 0) {
400
- const prefix = desktopClientsLikelyRunning()
401
- ? "Could not refresh the desktop model-picker cache because VS Code or Codex app is still running."
402
- : "Could not refresh the desktop model-picker cache.";
403
- return {
404
- patched,
405
- warnings: [`${prefix} ${warnings.join(" ")}`],
406
- };
407
- }
408
- if (patched > 0 && warnings.length > 0) {
409
- const filteredWarnings = warnings.filter((warning) => !/does not exist|No such file/i.test(warning));
410
- if (filteredWarnings.length > 0) {
411
- return { patched, warnings: filteredWarnings };
412
- }
413
- }
414
- return { patched, warnings: [] };
415
- }
416
- async function ensureCodexDesktopModelPickerSupport() {
417
- try {
418
- const bundleResult = await patchCodexWebviewBundles();
419
- const cacheResult = await patchDesktopStatsigCaches();
420
- const warning = cacheResult.warnings.length > 0 ? cacheResult.warnings.join(" ") : undefined;
421
- if (bundleResult.patched > 0 || cacheResult.patched > 0) {
422
- return {
423
- action: "patched",
424
- warning,
425
- patchedBundles: bundleResult.patched,
426
- patchedCaches: cacheResult.patched,
427
- };
428
- }
429
- if (warning) {
430
- return {
431
- action: "skipped",
432
- warning,
433
- patchedBundles: 0,
434
- patchedCaches: 0,
435
- };
436
- }
437
- return {
438
- action: "already_patched",
439
- patchedBundles: 0,
440
- patchedCaches: 0,
441
- };
442
- }
443
- catch (error) {
444
- const message = error instanceof Error ? error.message : String(error);
445
- return {
446
- action: "skipped",
447
- warning: `Could not refresh the desktop model picker: ${message}`,
448
- patchedBundles: 0,
449
- patchedCaches: 0,
450
- };
451
- }
452
- }
@@ -1,5 +0,0 @@
1
- type JsonObject = Record<string, unknown>;
2
- export declare function getHardcodedCodexModelCatalog(): JsonObject[];
3
- export declare function getHardcodedCodexModelIds(): string[];
4
- export declare function getVisibleHardcodedCodexModelIds(): string[];
5
- export {};
@@ -1,46 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getHardcodedCodexModelCatalog = getHardcodedCodexModelCatalog;
7
- exports.getHardcodedCodexModelIds = getHardcodedCodexModelIds;
8
- exports.getVisibleHardcodedCodexModelIds = getVisibleHardcodedCodexModelIds;
9
- const node_path_1 = __importDefault(require("node:path"));
10
- const node_fs_1 = require("node:fs");
11
- function configPath() {
12
- return node_path_1.default.resolve(__dirname, "..", "..", "theclawbay-codex-model-catalog.json");
13
- }
14
- function parseCodexModelCatalog(raw) {
15
- const parsed = JSON.parse(raw);
16
- if (!Array.isArray(parsed)) {
17
- throw new Error("codex model catalog must be an array");
18
- }
19
- return parsed.map((entry) => {
20
- if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
21
- throw new Error("codex model catalog contains an invalid entry");
22
- }
23
- return entry;
24
- });
25
- }
26
- function cloneJson(value) {
27
- return JSON.parse(JSON.stringify(value));
28
- }
29
- let cachedCatalog = null;
30
- function getHardcodedCodexModelCatalog() {
31
- if (!cachedCatalog) {
32
- cachedCatalog = parseCodexModelCatalog((0, node_fs_1.readFileSync)(configPath(), "utf8"));
33
- }
34
- return cloneJson(cachedCatalog);
35
- }
36
- function getHardcodedCodexModelIds() {
37
- return getHardcodedCodexModelCatalog()
38
- .map((model) => (typeof model.slug === "string" ? model.slug.trim() : ""))
39
- .filter(Boolean);
40
- }
41
- function getVisibleHardcodedCodexModelIds() {
42
- return getHardcodedCodexModelCatalog()
43
- .filter((model) => model.visibility === "list")
44
- .map((model) => (typeof model.slug === "string" ? model.slug.trim() : ""))
45
- .filter(Boolean);
46
- }