@getjack/jack 0.1.13 → 0.1.15

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/src/lib/hooks.ts CHANGED
@@ -83,50 +83,30 @@ const noopOutput: HookOutput = {
83
83
  */
84
84
 
85
85
  /**
86
- * Prompt user with numbered options (Claude Code style)
86
+ * Prompt user with numbered options
87
+ * Uses @clack/prompts selectKey for reliable input handling
87
88
  * Returns the selected option index (0-based) or -1 if cancelled
88
89
  */
89
90
  export async function promptSelect(options: string[]): Promise<number> {
90
- // Display options
91
- for (let i = 0; i < options.length; i++) {
92
- console.error(` ${i + 1}. ${options[i]}`);
93
- }
94
- console.error("");
95
- console.error(" Esc to skip");
96
-
97
- // Read single keypress
98
- if (process.stdin.isTTY) {
99
- process.stdin.setRawMode(true);
100
- }
101
- process.stdin.resume();
102
-
103
- return new Promise((resolve) => {
104
- const onData = (key: Buffer) => {
105
- const char = key.toString();
91
+ const { selectKey, isCancel } = await import("@clack/prompts");
106
92
 
107
- // Esc or q to cancel
108
- if (char === "\x1b" || char === "q") {
109
- cleanup();
110
- resolve(-1);
111
- return;
112
- }
93
+ // Build options with number keys (1, 2, 3, ...)
94
+ const clackOptions = options.map((label, index) => ({
95
+ value: String(index + 1),
96
+ label,
97
+ }));
113
98
 
114
- // Number keys
115
- const num = Number.parseInt(char, 10);
116
- if (num >= 1 && num <= options.length) {
117
- cleanup();
118
- resolve(num - 1);
119
- return;
120
- }
121
- };
99
+ const result = await selectKey({
100
+ message: "",
101
+ options: clackOptions,
102
+ });
122
103
 
123
- const cleanup = () => {
124
- process.stdin.removeListener("data", onData);
125
- restoreTty();
126
- };
104
+ if (isCancel(result)) {
105
+ return -1;
106
+ }
127
107
 
128
- process.stdin.on("data", onData);
129
- });
108
+ // Convert "1", "2", etc. back to 0-based index
109
+ return Number.parseInt(result as string, 10) - 1;
130
110
  }
131
111
 
132
112
  /**
@@ -446,15 +426,12 @@ const actionHandlers: {
446
426
  if (action.validate === "json" || action.validate === "accountAssociation") {
447
427
  rawValue = await readMultilineJson(action.message);
448
428
  } else {
449
- const { input } = await import("@inquirer/prompts");
450
- try {
451
- rawValue = await input({ message: action.message });
452
- } catch (err) {
453
- if (err instanceof Error && err.name === "ExitPromptError") {
454
- return true;
455
- }
456
- throw err;
429
+ const { isCancel, text } = await import("@clack/prompts");
430
+ const result = await text({ message: action.message });
431
+ if (isCancel(result)) {
432
+ return true;
457
433
  }
434
+ rawValue = result;
458
435
  }
459
436
 
460
437
  if (!rawValue.trim()) {