fix(macos): mask sensitive wizard cli prompts

This commit is contained in:
sallyom
2026-05-03 10:49:44 -04:00
parent 727398f41a
commit 8a63773e22
2 changed files with 32 additions and 0 deletions

View File

@@ -25,6 +25,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Agents/models: forward model `maxTokens` as the default output-token limit for OpenAI-compatible Responses and Completions transports when no runtime override is provided, preventing provider defaults from silently truncating larger outputs. (#76645) Thanks @joeyfrasier.
- macOS CLI/onboarding: honor sensitive wizard text steps in `openclaw-mac wizard` with termios no-echo input, suppressing saved credential previews while preserving long API keys and gateway tokens. Fixes #76698. Thanks @anurag-bg-neu and @sallyom.
- Control UI/Skills: fix skill detail modal silently failing to open in all browsers by deferring `showModal()` until the dialog element is connected to the DOM; the Lit `ref` callback fired before connection causing a `DOMException: HTMLDialogElement.showModal: Dialog element is not connected` on every skill click. Thanks @nickmopen.
- Gateway/update: run `doctor --non-interactive --fix` after Control UI global package updates before reporting success, so legacy config is migrated before the gateway restart. Thanks @stevenchouai.
- Gateway/cron: stop a lazy cron startup that loses a hot-reload race, preventing the old cron service from starting after reload has already replaced cron state.

View File

@@ -445,6 +445,12 @@ private func promptAnswer(for step: WizardStep) throws -> Any {
case "text":
let initial = anyCodableString(step.initialvalue)
let prompt = step.placeholder ?? "Value"
if step.sensitive == true {
let sensitivePrompt = initial.isEmpty ? prompt : "\(prompt) (leave blank to keep existing)"
let value = try readSensitiveLineWithPrompt(sensitivePrompt)
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
return trimmed.isEmpty ? initial : trimmed
}
let value = try readLineWithPrompt("\(prompt)\(initial.isEmpty ? "" : " [\(initial)]")")
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
return trimmed.isEmpty ? initial : trimmed
@@ -524,3 +530,28 @@ private func readLineWithPrompt(_ prompt: String) throws -> String {
}
return line
}
private func readSensitiveLineWithPrompt(_ prompt: String) throws -> String {
print("\(prompt): ", terminator: "")
fflush(stdout)
var original = termios()
guard tcgetattr(STDIN_FILENO, &original) == 0 else {
throw WizardCliError.gatewayError("Could not configure hidden terminal input.")
}
var hidden = original
hidden.c_lflag &= ~tcflag_t(ECHO)
guard tcsetattr(STDIN_FILENO, TCSANOW, &hidden) == 0 else {
throw WizardCliError.gatewayError("Could not configure hidden terminal input.")
}
defer {
_ = tcsetattr(STDIN_FILENO, TCSANOW, &original)
print("")
}
guard let line = readLine() else {
throw WizardCliError.cancelled
}
return line
}