@fclef819/cdx 0.1.2 → 0.1.4
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 +55 -79
- package/package.json +1 -1
package/bin/cdx.js
CHANGED
|
@@ -153,6 +153,14 @@ function getNewestHistorySessionIdSince(previousId, verbose) {
|
|
|
153
153
|
|
|
154
154
|
function runCodex(args, cwd, verbose) {
|
|
155
155
|
logVerbose(`Running codex ${args.join(" ")}`.trim(), verbose);
|
|
156
|
+
if (process.stdin.isTTY) {
|
|
157
|
+
try {
|
|
158
|
+
process.stdin.setRawMode(false);
|
|
159
|
+
} catch {
|
|
160
|
+
// ignore if not supported
|
|
161
|
+
}
|
|
162
|
+
process.stdin.pause();
|
|
163
|
+
}
|
|
156
164
|
const result = spawnSync("codex", args, { stdio: "inherit", cwd });
|
|
157
165
|
if (result.error) {
|
|
158
166
|
if (result.error.code === "ENOENT" && process.platform === "win32") {
|
|
@@ -167,8 +175,7 @@ function runCodex(args, cwd, verbose) {
|
|
|
167
175
|
cwd
|
|
168
176
|
});
|
|
169
177
|
if (!psResult.error) {
|
|
170
|
-
|
|
171
|
-
return;
|
|
178
|
+
return { status: psResult.status ?? 0 };
|
|
172
179
|
}
|
|
173
180
|
}
|
|
174
181
|
console.error(
|
|
@@ -176,14 +183,18 @@ function runCodex(args, cwd, verbose) {
|
|
|
176
183
|
);
|
|
177
184
|
process.exit(1);
|
|
178
185
|
}
|
|
179
|
-
|
|
186
|
+
return { status: result.status ?? 0 };
|
|
180
187
|
}
|
|
181
188
|
|
|
182
|
-
function
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
function suggestByNumber(input, choices) {
|
|
190
|
+
const term = (input || "").trim();
|
|
191
|
+
if (!term) return choices;
|
|
192
|
+
if (/^\d+$/.test(term)) {
|
|
193
|
+
const number = Number.parseInt(term, 10);
|
|
194
|
+
return choices.filter((choice) => choice.number === number);
|
|
195
|
+
}
|
|
196
|
+
const lower = term.toLowerCase();
|
|
197
|
+
return choices.filter((choice) => choice.title.toLowerCase().includes(lower));
|
|
187
198
|
}
|
|
188
199
|
|
|
189
200
|
async function selectSession(entries) {
|
|
@@ -191,41 +202,21 @@ async function selectSession(entries) {
|
|
|
191
202
|
return { type: "new" };
|
|
192
203
|
}
|
|
193
204
|
|
|
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
|
-
|
|
216
205
|
const choices = [
|
|
217
|
-
{ title: "new", value: { type: "new" } },
|
|
218
|
-
...entries.map((entry) => ({
|
|
219
|
-
title: `${entry.label} (${entry.uuid})`,
|
|
220
|
-
value: { type: "resume", entry }
|
|
206
|
+
{ title: "0: new", value: { type: "new" }, number: 0 },
|
|
207
|
+
...entries.map((entry, index) => ({
|
|
208
|
+
title: `${index + 1}: ${entry.label} (${entry.uuid})`,
|
|
209
|
+
value: { type: "resume", entry },
|
|
210
|
+
number: index + 1
|
|
221
211
|
}))
|
|
222
212
|
];
|
|
223
213
|
|
|
224
214
|
const response = await prompts({
|
|
225
|
-
type: "
|
|
215
|
+
type: "autocomplete",
|
|
226
216
|
name: "selection",
|
|
227
|
-
message: "Select a session",
|
|
228
|
-
choices
|
|
217
|
+
message: "Select a session (arrow keys or number+Enter)",
|
|
218
|
+
choices,
|
|
219
|
+
suggest: suggestByNumber
|
|
229
220
|
});
|
|
230
221
|
|
|
231
222
|
return response.selection;
|
|
@@ -269,7 +260,7 @@ async function runDefault(startDir, options) {
|
|
|
269
260
|
const label = sanitizeLabel(labelInput);
|
|
270
261
|
const previousHistoryId = getLastHistorySessionId(options.verbose);
|
|
271
262
|
const previousSession = getLatestSessionSnapshot(options.verbose);
|
|
272
|
-
runCodex([], workDir, options.verbose);
|
|
263
|
+
const codexResult = runCodex([], workDir, options.verbose);
|
|
273
264
|
const latestSession = getLatestSessionSnapshot(options.verbose);
|
|
274
265
|
let newId = null;
|
|
275
266
|
if (
|
|
@@ -285,14 +276,27 @@ async function runDefault(startDir, options) {
|
|
|
285
276
|
}
|
|
286
277
|
if (!newId) {
|
|
287
278
|
console.error("Could not determine new session UUID; not updating .cdx.");
|
|
279
|
+
if (codexResult && codexResult.status !== 0) {
|
|
280
|
+
process.exit(codexResult.status);
|
|
281
|
+
}
|
|
288
282
|
return;
|
|
289
283
|
}
|
|
290
284
|
appendEntry(cdxPath, { uuid: newId, label }, options.verbose);
|
|
285
|
+
if (codexResult && codexResult.status !== 0) {
|
|
286
|
+
process.exit(codexResult.status);
|
|
287
|
+
}
|
|
291
288
|
return;
|
|
292
289
|
}
|
|
293
290
|
|
|
294
291
|
if (selection.type === "resume") {
|
|
295
|
-
|
|
292
|
+
const codexResult = runCodex(
|
|
293
|
+
["resume", selection.entry.uuid],
|
|
294
|
+
workDir,
|
|
295
|
+
options.verbose
|
|
296
|
+
);
|
|
297
|
+
if (codexResult && codexResult.status !== 0) {
|
|
298
|
+
process.exit(codexResult.status);
|
|
299
|
+
}
|
|
296
300
|
}
|
|
297
301
|
}
|
|
298
302
|
|
|
@@ -310,48 +314,20 @@ async function runRemove(startDir, verbose) {
|
|
|
310
314
|
}
|
|
311
315
|
|
|
312
316
|
console.log(`.cdx: ${targetPath}`);
|
|
313
|
-
|
|
314
|
-
|
|
317
|
+
const response = await prompts({
|
|
318
|
+
type: "autocomplete",
|
|
319
|
+
name: "selection",
|
|
320
|
+
message: "Select a session to remove (arrow keys or number+Enter)",
|
|
321
|
+
choices: entries.map((entry, index) => ({
|
|
322
|
+
title: `${index + 1}: ${entry.label} (${entry.uuid})`,
|
|
323
|
+
value: entry.uuid,
|
|
324
|
+
number: index + 1
|
|
325
|
+
})),
|
|
326
|
+
suggest: suggestByNumber
|
|
315
327
|
});
|
|
316
328
|
|
|
317
|
-
|
|
318
|
-
|
|
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);
|
|
329
|
+
if (!response.selection) return;
|
|
330
|
+
const remaining = entries.filter((entry) => entry.uuid !== response.selection);
|
|
355
331
|
writeEntries(targetPath, remaining, verbose);
|
|
356
332
|
}
|
|
357
333
|
|