@fclef819/cdx 0.1.1 → 0.1.2
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/bin/cdx.js +96 -17
- package/package.json +1 -1
package/bin/cdx.js
CHANGED
|
@@ -15,6 +15,11 @@ function logVerbose(message, enabled) {
|
|
|
15
15
|
if (enabled) console.log(message);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
function escapePowerShellArg(value) {
|
|
19
|
+
if (value === "") return "''";
|
|
20
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
function findCdxFile(startDir, verbose) {
|
|
19
24
|
let dir = path.resolve(startDir);
|
|
20
25
|
while (true) {
|
|
@@ -148,22 +153,66 @@ function getNewestHistorySessionIdSince(previousId, verbose) {
|
|
|
148
153
|
|
|
149
154
|
function runCodex(args, cwd, verbose) {
|
|
150
155
|
logVerbose(`Running codex ${args.join(" ")}`.trim(), verbose);
|
|
151
|
-
const
|
|
152
|
-
if (
|
|
156
|
+
const result = spawnSync("codex", args, { stdio: "inherit", cwd });
|
|
157
|
+
if (result.error) {
|
|
158
|
+
if (result.error.code === "ENOENT" && process.platform === "win32") {
|
|
159
|
+
logVerbose("codex not found directly; trying PowerShell fallback", verbose);
|
|
160
|
+
const psArgs = [
|
|
161
|
+
"-NoProfile",
|
|
162
|
+
"-Command",
|
|
163
|
+
["codex", ...args.map(escapePowerShellArg)].join(" ")
|
|
164
|
+
];
|
|
165
|
+
const psResult = spawnSync("powershell.exe", psArgs, {
|
|
166
|
+
stdio: "inherit",
|
|
167
|
+
cwd
|
|
168
|
+
});
|
|
169
|
+
if (!psResult.error) {
|
|
170
|
+
if (psResult.status !== 0) process.exit(psResult.status ?? 1);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
153
174
|
console.error(
|
|
154
175
|
"Codex CLI is not available. Please install it and ensure `codex` is on your PATH."
|
|
155
176
|
);
|
|
156
177
|
process.exit(1);
|
|
157
178
|
}
|
|
158
|
-
const result = spawnSync("codex", args, { stdio: "inherit", cwd });
|
|
159
|
-
if (result.error) {
|
|
160
|
-
console.error("Failed to run codex:", result.error.message);
|
|
161
|
-
process.exit(result.status ?? 1);
|
|
162
|
-
}
|
|
163
179
|
if (result.status !== 0) process.exit(result.status ?? 1);
|
|
164
180
|
}
|
|
165
181
|
|
|
182
|
+
function printSessionList(entries) {
|
|
183
|
+
console.log("0: new");
|
|
184
|
+
entries.forEach((entry, index) => {
|
|
185
|
+
console.log(`${index + 1}: ${entry.label} (${entry.uuid})`);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
166
189
|
async function selectSession(entries) {
|
|
190
|
+
if (!entries.length) {
|
|
191
|
+
return { type: "new" };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
printSessionList(entries);
|
|
195
|
+
while (true) {
|
|
196
|
+
const numberInput = await prompts({
|
|
197
|
+
type: "text",
|
|
198
|
+
name: "value",
|
|
199
|
+
message: "Select by number (Enter for list selection)",
|
|
200
|
+
validate: (value) => {
|
|
201
|
+
if (!value || !value.trim()) return true;
|
|
202
|
+
if (!/^\d+$/.test(value.trim())) return "Enter a number";
|
|
203
|
+
const index = Number.parseInt(value.trim(), 10);
|
|
204
|
+
if (index < 0 || index > entries.length) return "Out of range";
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
if (!numberInput.value && numberInput.value !== "0") break;
|
|
210
|
+
const index = Number.parseInt(String(numberInput.value).trim(), 10);
|
|
211
|
+
if (Number.isNaN(index)) break;
|
|
212
|
+
if (index === 0) return { type: "new" };
|
|
213
|
+
return { type: "resume", entry: entries[index - 1] };
|
|
214
|
+
}
|
|
215
|
+
|
|
167
216
|
const choices = [
|
|
168
217
|
{ title: "new", value: { type: "new" } },
|
|
169
218
|
...entries.map((entry) => ({
|
|
@@ -261,18 +310,48 @@ async function runRemove(startDir, verbose) {
|
|
|
261
310
|
}
|
|
262
311
|
|
|
263
312
|
console.log(`.cdx: ${targetPath}`);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
name: "selection",
|
|
267
|
-
message: "Select a session to remove",
|
|
268
|
-
choices: entries.map((entry) => ({
|
|
269
|
-
title: `${entry.label} (${entry.uuid})`,
|
|
270
|
-
value: entry.uuid
|
|
271
|
-
}))
|
|
313
|
+
entries.forEach((entry, index) => {
|
|
314
|
+
console.log(`${index + 1}: ${entry.label} (${entry.uuid})`);
|
|
272
315
|
});
|
|
273
316
|
|
|
274
|
-
|
|
275
|
-
|
|
317
|
+
let selectedUuid = null;
|
|
318
|
+
while (true) {
|
|
319
|
+
const numberInput = await prompts({
|
|
320
|
+
type: "text",
|
|
321
|
+
name: "value",
|
|
322
|
+
message: "Select by number (Enter for list selection)",
|
|
323
|
+
validate: (value) => {
|
|
324
|
+
if (!value || !value.trim()) return true;
|
|
325
|
+
if (!/^\d+$/.test(value.trim())) return "Enter a number";
|
|
326
|
+
const index = Number.parseInt(value.trim(), 10);
|
|
327
|
+
if (index < 1 || index > entries.length) return "Out of range";
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
if (!numberInput.value) break;
|
|
333
|
+
const index = Number.parseInt(String(numberInput.value).trim(), 10);
|
|
334
|
+
if (!Number.isNaN(index)) {
|
|
335
|
+
selectedUuid = entries[index - 1].uuid;
|
|
336
|
+
}
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (!selectedUuid) {
|
|
341
|
+
const response = await prompts({
|
|
342
|
+
type: "select",
|
|
343
|
+
name: "selection",
|
|
344
|
+
message: "Select a session to remove",
|
|
345
|
+
choices: entries.map((entry) => ({
|
|
346
|
+
title: `${entry.label} (${entry.uuid})`,
|
|
347
|
+
value: entry.uuid
|
|
348
|
+
}))
|
|
349
|
+
});
|
|
350
|
+
if (!response.selection) return;
|
|
351
|
+
selectedUuid = response.selection;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const remaining = entries.filter((entry) => entry.uuid !== selectedUuid);
|
|
276
355
|
writeEntries(targetPath, remaining, verbose);
|
|
277
356
|
}
|
|
278
357
|
|