mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-09 11:10:10 +00:00
fix: resolve DigitalOcean token input validation bug (#1720)
Reuse a single readline interface across prompt() calls instead of creating and closing a new one each time. In Bun, repeatedly calling createInterface/close on the same stdin causes the "close" event to fire immediately on subsequent interfaces, which resolved the prompt with an empty string before the user could type — triggering "Token cannot be empty". Fixes #1707 Agent: code-health Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
3204ce8eec
commit
be72d573e1
1 changed files with 15 additions and 5 deletions
|
|
@ -26,19 +26,29 @@ export function logStep(msg: string): void {
|
|||
process.stderr.write(`${CYAN}${msg}${NC}\n`);
|
||||
}
|
||||
|
||||
// Shared readline interface — reused across prompt() calls to avoid Bun's
|
||||
// issue where repeatedly creating/closing interfaces on the same stdin causes
|
||||
// the "close" event to fire immediately on subsequent interfaces (#1707).
|
||||
let sharedRl: ReturnType<typeof createInterface> | null = null;
|
||||
|
||||
function getReadlineInterface(): ReturnType<typeof createInterface> {
|
||||
if (!sharedRl) {
|
||||
sharedRl = createInterface({ input: process.stdin, output: process.stderr });
|
||||
sharedRl.on("close", () => { sharedRl = null; });
|
||||
}
|
||||
return sharedRl;
|
||||
}
|
||||
|
||||
/** Prompt for a line of user input. Throws if non-interactive. */
|
||||
export async function prompt(question: string): Promise<string> {
|
||||
if (process.env.SPAWN_NON_INTERACTIVE === "1") {
|
||||
throw new Error("Cannot prompt: SPAWN_NON_INTERACTIVE is set");
|
||||
}
|
||||
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const rl = getReadlineInterface();
|
||||
return new Promise<string>((resolve) => {
|
||||
rl.question(question, (answer) => {
|
||||
rl.close();
|
||||
resolve(answer.trim());
|
||||
});
|
||||
rl.on("error", reject);
|
||||
rl.on("close", () => resolve(""));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue