Explain that daemon set-password needs a terminal when stdin is piped (#5358)

* Explain that daemon set-password needs a terminal when stdin is piped

The password prompt only resolves on a keypress from a terminal. With
stdin piped or redirected it never settled, so Node exited 13 with an
unsettled top-level await warning and no message. The command now fails
with PASSWORD_TTY_REQUIRED and points at PASEO_PASSWORD.

Closes #5350

* Assert the set-password terminal error message

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
paseo-bot[bot]
2026-09-25 06:54:28 +02:00
committed by GitHub
parent 5c9f767d51
commit bf4dc22c2f
2 changed files with 34 additions and 1 deletions
@@ -6,6 +6,7 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import type { Command } from "commander";
import { isBearerTokenValid } from "@getpaseo/server/auth";
import { runLocalPaseo } from "./helpers/local-cli.ts";
import {
runSetPasswordCommand,
setDaemonPasswordInConfig,
@@ -105,6 +106,27 @@ try {
);
console.log("✓ command refuses password mismatch\n");
}
{
console.log("Test 4: piped stdin fails with a message instead of exiting silently");
const pipedHome = join(root, "piped");
await mkdir(pipedHome, { recursive: true });
const run = runLocalPaseo(["daemon", "set-password", "--home", pipedHome, "--json"]);
run.stdin.end("x\nx\n");
const result = await run;
assert.strictEqual(result.exitCode, 1, result.stderr);
const error = JSON.parse(result.stderr).error as {
code: string;
message: string;
details: string;
};
assert.strictEqual(error.code, "PASSWORD_TTY_REQUIRED");
assert.match(error.message, /needs a terminal/);
assert.match(error.details, /PASEO_PASSWORD/);
await assert.rejects(readFile(join(pipedHome, "config.json"), "utf-8"));
console.log("✓ piped stdin reports that a terminal is required\n");
}
} finally {
await rm(root, { recursive: true, force: true });
}