@childclm/codexx 0.1.0 → 0.1.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/package.json +1 -1
- package/src/index.js +173 -4
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -97,6 +97,14 @@ function loadSettings() {
|
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
function fileExists(p) {
|
|
101
|
+
try {
|
|
102
|
+
return fs.existsSync(p);
|
|
103
|
+
} catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
100
108
|
function loadProject(cwd = process.cwd()) {
|
|
101
109
|
const { root, projectFile } = getProjectPaths(cwd);
|
|
102
110
|
return readJson(projectFile, {
|
|
@@ -132,10 +140,170 @@ function detectCodex() {
|
|
|
132
140
|
return settings.codexCommand || "codex";
|
|
133
141
|
}
|
|
134
142
|
|
|
143
|
+
function resolveWindowsCodexCandidates() {
|
|
144
|
+
const candidates = [];
|
|
145
|
+
const appData = process.env.APPDATA || path.join(HOME, "AppData", "Roaming");
|
|
146
|
+
const npmRoot = path.join(appData, "npm");
|
|
147
|
+
const localShims = [
|
|
148
|
+
path.join(npmRoot, "codex.exe"),
|
|
149
|
+
path.join(npmRoot, "codex.cmd"),
|
|
150
|
+
path.join(npmRoot, "codex"),
|
|
151
|
+
];
|
|
152
|
+
candidates.push(...localShims);
|
|
153
|
+
|
|
154
|
+
const openaiCodexRoot = path.join(
|
|
155
|
+
npmRoot,
|
|
156
|
+
"node_modules",
|
|
157
|
+
"@openai",
|
|
158
|
+
"codex",
|
|
159
|
+
"node_modules",
|
|
160
|
+
);
|
|
161
|
+
if (fileExists(openaiCodexRoot)) {
|
|
162
|
+
try {
|
|
163
|
+
const children = fs.readdirSync(openaiCodexRoot);
|
|
164
|
+
for (const child of children) {
|
|
165
|
+
if (!child.startsWith("@openai\\codex-win32-") && !child.startsWith("@openai/codex-win32-")) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} catch {}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const finder = spawnSync("where", ["codex.exe"], { encoding: "utf8" });
|
|
173
|
+
const foundExe = (finder.stdout || "")
|
|
174
|
+
.trim()
|
|
175
|
+
.split(/\r?\n/)
|
|
176
|
+
.filter(Boolean);
|
|
177
|
+
candidates.push(...foundExe);
|
|
178
|
+
|
|
179
|
+
const foundCmd = spawnSync("where", ["codex.cmd"], { encoding: "utf8" });
|
|
180
|
+
const cmdHits = (foundCmd.stdout || "")
|
|
181
|
+
.trim()
|
|
182
|
+
.split(/\r?\n/)
|
|
183
|
+
.filter(Boolean);
|
|
184
|
+
candidates.push(...cmdHits);
|
|
185
|
+
|
|
186
|
+
const vendorGlobRoot = path.join(
|
|
187
|
+
npmRoot,
|
|
188
|
+
"node_modules",
|
|
189
|
+
"@openai",
|
|
190
|
+
"codex",
|
|
191
|
+
"node_modules",
|
|
192
|
+
);
|
|
193
|
+
if (fileExists(vendorGlobRoot)) {
|
|
194
|
+
try {
|
|
195
|
+
const dirs = fs.readdirSync(vendorGlobRoot);
|
|
196
|
+
for (const dir of dirs) {
|
|
197
|
+
if (!dir.startsWith("@openai")) continue;
|
|
198
|
+
}
|
|
199
|
+
} catch {}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const packageRoot = path.join(
|
|
203
|
+
npmRoot,
|
|
204
|
+
"node_modules",
|
|
205
|
+
"@openai",
|
|
206
|
+
"codex",
|
|
207
|
+
"node_modules",
|
|
208
|
+
);
|
|
209
|
+
if (fileExists(packageRoot)) {
|
|
210
|
+
try {
|
|
211
|
+
const entries = fs.readdirSync(packageRoot);
|
|
212
|
+
for (const entry of entries) {
|
|
213
|
+
if (!entry.startsWith("@openai")) continue;
|
|
214
|
+
}
|
|
215
|
+
} catch {}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const openaiNodeModules = path.join(
|
|
219
|
+
npmRoot,
|
|
220
|
+
"node_modules",
|
|
221
|
+
"@openai",
|
|
222
|
+
"codex",
|
|
223
|
+
"node_modules",
|
|
224
|
+
);
|
|
225
|
+
if (fileExists(openaiNodeModules)) {
|
|
226
|
+
try {
|
|
227
|
+
const entries = fs.readdirSync(openaiNodeModules);
|
|
228
|
+
for (const entry of entries) {
|
|
229
|
+
if (!entry.startsWith("@openai")) continue;
|
|
230
|
+
}
|
|
231
|
+
} catch {}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const codexNodeModules = path.join(
|
|
235
|
+
npmRoot,
|
|
236
|
+
"node_modules",
|
|
237
|
+
"@openai",
|
|
238
|
+
"codex",
|
|
239
|
+
"node_modules",
|
|
240
|
+
);
|
|
241
|
+
if (fileExists(codexNodeModules)) {
|
|
242
|
+
try {
|
|
243
|
+
const entries = fs.readdirSync(codexNodeModules);
|
|
244
|
+
for (const entry of entries) {
|
|
245
|
+
if (!entry.startsWith("@openai")) continue;
|
|
246
|
+
}
|
|
247
|
+
} catch {}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const directVendorParent = path.join(
|
|
251
|
+
npmRoot,
|
|
252
|
+
"node_modules",
|
|
253
|
+
"@openai",
|
|
254
|
+
"codex",
|
|
255
|
+
"node_modules",
|
|
256
|
+
);
|
|
257
|
+
if (fileExists(directVendorParent)) {
|
|
258
|
+
try {
|
|
259
|
+
const dirs = fs.readdirSync(directVendorParent);
|
|
260
|
+
for (const dir of dirs) {
|
|
261
|
+
if (!dir.includes("codex-win32-")) continue;
|
|
262
|
+
const vendorRoot = path.join(directVendorParent, dir, "vendor");
|
|
263
|
+
if (!fileExists(vendorRoot)) continue;
|
|
264
|
+
const vendorDirs = fs.readdirSync(vendorRoot);
|
|
265
|
+
for (const vendorDir of vendorDirs) {
|
|
266
|
+
const exePath = path.join(vendorRoot, vendorDir, "bin", "codex.exe");
|
|
267
|
+
candidates.push(exePath);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
} catch {}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return [...new Set(candidates)].filter(Boolean);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function resolveCodexCommand() {
|
|
277
|
+
const configured = detectCodex();
|
|
278
|
+
if (path.isAbsolute(configured) && fileExists(configured)) {
|
|
279
|
+
return configured;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (process.platform === "win32") {
|
|
283
|
+
const candidates = [];
|
|
284
|
+
if (configured && configured !== "codex") {
|
|
285
|
+
candidates.push(configured);
|
|
286
|
+
if (!path.extname(configured)) {
|
|
287
|
+
candidates.push(`${configured}.exe`, `${configured}.cmd`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
candidates.push(...resolveWindowsCodexCandidates());
|
|
291
|
+
|
|
292
|
+
for (const candidate of candidates) {
|
|
293
|
+
if (candidate && fileExists(candidate)) {
|
|
294
|
+
return candidate;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return configured;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const finder = spawnSync("which", [configured], { encoding: "utf8" });
|
|
301
|
+
const found = (finder.stdout || "").trim().split(/\r?\n/)[0] || "";
|
|
302
|
+
return found || configured;
|
|
303
|
+
}
|
|
304
|
+
|
|
135
305
|
function codexPath() {
|
|
136
|
-
|
|
137
|
-
const out = spawnSync(finder, ["codex"], { encoding: "utf8" });
|
|
138
|
-
return (out.stdout || "").trim().split(/\r?\n/)[0] || "";
|
|
306
|
+
return resolveCodexCommand();
|
|
139
307
|
}
|
|
140
308
|
|
|
141
309
|
function clearScreen() {
|
|
@@ -353,11 +521,12 @@ function buildCodexEnv(provider) {
|
|
|
353
521
|
|
|
354
522
|
function runCodex(args, env, cwd = process.cwd()) {
|
|
355
523
|
return new Promise((resolve, reject) => {
|
|
356
|
-
const cmd =
|
|
524
|
+
const cmd = resolveCodexCommand();
|
|
357
525
|
const child = spawn(cmd, args, {
|
|
358
526
|
cwd,
|
|
359
527
|
stdio: "inherit",
|
|
360
528
|
env: { ...process.env, ...env },
|
|
529
|
+
shell: false,
|
|
361
530
|
});
|
|
362
531
|
child.on("error", reject);
|
|
363
532
|
child.on("exit", (code) => resolve(code ?? 0));
|