commit 76c4ad841a0e6a31673b79c0424a3aa941e6b08d
parent 275eefd1b3338fe3788db29fe1c972dd425110e5
Author: Florian Dold <dold@taler.net>
Date: Thu, 6 Aug 2026 15:39:55 +0200
wallet-cli: add --interactive to force prompting
Only the opposite could be forced, so a wallet driven from a script that
happened to set TALER_WALLET_NONINTERACTIVE had no way back.
Diffstat:
1 file changed, 36 insertions(+), 0 deletions(-)
diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts
@@ -301,8 +301,32 @@ async function doPay(
}
let globalNonInteractive = false;
+let globalInteractive = false;
+
+/**
+ * Reject interactivity flags that can't be honored.
+ *
+ * Called from both flag handlers, since either one may come first.
+ */
+function validateInteractivity(): void {
+ if (globalInteractive && globalNonInteractive) {
+ console.error(
+ "error: --interactive and --non-interactive are mutually exclusive",
+ );
+ processExit(EXIT_USAGE);
+ }
+ if (globalInteractive && !process.stdin.isTTY) {
+ console.error("error: --interactive requires stdin to be a terminal");
+ processExit(EXIT_USAGE);
+ }
+}
function isNonInteractive(): boolean {
+ // An explicit --interactive outranks the environment, which is
+ // otherwise easy to inherit by accident.
+ if (globalInteractive) {
+ return false;
+ }
return (
globalNonInteractive ||
checkEnvFlag("TALER_WALLET_NONINTERACTIVE") ||
@@ -401,6 +425,14 @@ export const walletCli = clk
help: "Never ask for input; fail instead. Implied when stdin is not a terminal.",
onPresentHandler: () => {
globalNonInteractive = true;
+ validateInteractivity();
+ },
+ })
+ .flag("interactive", ["--interactive"], {
+ help: "Ask for input even when the environment says not to; fail if stdin is not a terminal.",
+ onPresentHandler: () => {
+ globalInteractive = true;
+ validateInteractivity();
},
})
.flag("noThrottle", ["--no-throttle"], {
@@ -1583,6 +1615,10 @@ walletCli
.maybeOption("restrictAge", ["--restrict-age"], clk.INT)
.flag("nonInteractive", ["--non-interactive"], {
help: "Deprecated, use the global --non-interactive.",
+ onPresentHandler: () => {
+ globalNonInteractive = true;
+ validateInteractivity();
+ },
})
.flag("autoYes", ["-y", "--yes"])
.action(async (args) => {