@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.
Files changed (2) hide show
  1. package/bin/cdx.js +55 -20
  2. 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 check = spawnSync("codex", ["--version"], { stdio: "ignore" });
152
- if (check.error && check.error.code === "ENOENT") {
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: "select",
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: "select",
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fclef819/cdx",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Codex session wrapper",
5
5
  "keywords": [
6
6
  "codex",