@fclef819/cdx 0.1.1 → 0.1.3
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 -20
- 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,35 +153,63 @@ 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 suggestByNumber(input, choices) {
|
|
183
|
+
const term = (input || "").trim();
|
|
184
|
+
if (!term) return choices;
|
|
185
|
+
if (/^\d+$/.test(term)) {
|
|
186
|
+
const number = Number.parseInt(term, 10);
|
|
187
|
+
return choices.filter((choice) => choice.number === number);
|
|
188
|
+
}
|
|
189
|
+
const lower = term.toLowerCase();
|
|
190
|
+
return choices.filter((choice) => choice.title.toLowerCase().includes(lower));
|
|
191
|
+
}
|
|
192
|
+
|
|
166
193
|
async function selectSession(entries) {
|
|
194
|
+
if (!entries.length) {
|
|
195
|
+
return { type: "new" };
|
|
196
|
+
}
|
|
197
|
+
|
|
167
198
|
const choices = [
|
|
168
|
-
{ title: "new", value: { type: "new" } },
|
|
169
|
-
...entries.map((entry) => ({
|
|
170
|
-
title: `${entry.label} (${entry.uuid})`,
|
|
171
|
-
value: { type: "resume", entry }
|
|
199
|
+
{ title: "0: new", value: { type: "new" }, number: 0 },
|
|
200
|
+
...entries.map((entry, index) => ({
|
|
201
|
+
title: `${index + 1}: ${entry.label} (${entry.uuid})`,
|
|
202
|
+
value: { type: "resume", entry },
|
|
203
|
+
number: index + 1
|
|
172
204
|
}))
|
|
173
205
|
];
|
|
174
206
|
|
|
175
207
|
const response = await prompts({
|
|
176
|
-
type: "
|
|
208
|
+
type: "autocomplete",
|
|
177
209
|
name: "selection",
|
|
178
|
-
message: "Select a session",
|
|
179
|
-
choices
|
|
210
|
+
message: "Select a session (arrow keys or number+Enter)",
|
|
211
|
+
choices,
|
|
212
|
+
suggest: suggestByNumber
|
|
180
213
|
});
|
|
181
214
|
|
|
182
215
|
return response.selection;
|
|
@@ -262,13 +295,15 @@ async function runRemove(startDir, verbose) {
|
|
|
262
295
|
|
|
263
296
|
console.log(`.cdx: ${targetPath}`);
|
|
264
297
|
const response = await prompts({
|
|
265
|
-
type: "
|
|
298
|
+
type: "autocomplete",
|
|
266
299
|
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
|
-
|
|
300
|
+
message: "Select a session to remove (arrow keys or number+Enter)",
|
|
301
|
+
choices: entries.map((entry, index) => ({
|
|
302
|
+
title: `${index + 1}: ${entry.label} (${entry.uuid})`,
|
|
303
|
+
value: entry.uuid,
|
|
304
|
+
number: index + 1
|
|
305
|
+
})),
|
|
306
|
+
suggest: suggestByNumber
|
|
272
307
|
});
|
|
273
308
|
|
|
274
309
|
if (!response.selection) return;
|