mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(installer): handle headless onboarding tty
This commit is contained in:
@@ -76,11 +76,9 @@ jobs:
|
||||
- name: install.sh in Docker
|
||||
run: |
|
||||
docker run --rm \
|
||||
-e OPENCLAW_NO_ONBOARD=1 \
|
||||
-e OPENCLAW_NO_PROMPT=1 \
|
||||
-v "$PWD/scripts/install.sh:/tmp/install.sh:ro" \
|
||||
node:24-bookworm-slim \
|
||||
bash -lc 'bash /tmp/install.sh --no-prompt --no-onboard --version latest && openclaw --version'
|
||||
bash -lc 'bash /tmp/install.sh --version latest && openclaw --version'
|
||||
|
||||
- name: install-cli.sh in Docker
|
||||
run: |
|
||||
|
||||
@@ -26,6 +26,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Providers/Ollama: treat Docker/OrbStack host aliases as local Ollama endpoints so `ollama-local` marker auth works when OpenClaw runs inside a VM/container and Ollama runs on the host. Fixes #84875.
|
||||
- QA-Lab: keep explicitly searchable/deferred OpenClaw dynamic tool rows report-only by default so tool-coverage gates do not treat mock discovery gaps as hard product failures. (#80319) Thanks @100yenadmin.
|
||||
- Agents/config: keep non-Google provider model refs from being rewritten by Google Gemini preview-id normalization. (#84762) Thanks @zhangguiping-xydt.
|
||||
- Installer: require a real controlling terminal before launching onboarding so headless `curl | bash` installs finish cleanly after installing the CLI.
|
||||
- Agents: cap heartbeat model bleed context hints by the stored session window when runtime model metadata is unavailable, so overflow recovery advice does not suggest a larger window than the active session actually has.
|
||||
- Control UI/Web Push: use `https://openclaw.ai` as the generated default VAPID subject instead of the old localhost mailbox so iOS PWA push setup uses an Apple-acceptable subject when `OPENCLAW_VAPID_SUBJECT` is unset. Fixes #83134. (#83317) Thanks @IWhatsskill.
|
||||
- Agents/Pi: keep embedded session transcript writes from tripping false takeover detection after packaged npm onboarding agent turns.
|
||||
|
||||
+15
-5
@@ -90,6 +90,16 @@ is_non_interactive_shell() {
|
||||
return 1
|
||||
}
|
||||
|
||||
has_controlling_tty() {
|
||||
if [[ ! -r /dev/tty || ! -w /dev/tty ]]; then
|
||||
return 1
|
||||
fi
|
||||
if ! { : </dev/tty; } 2>/dev/null; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
gum_is_tty() {
|
||||
if [[ -n "${NO_COLOR:-}" ]]; then
|
||||
return 1
|
||||
@@ -100,7 +110,7 @@ gum_is_tty() {
|
||||
if [[ -t 2 || -t 1 ]]; then
|
||||
return 0
|
||||
fi
|
||||
if [[ -r /dev/tty && -w /dev/tty ]]; then
|
||||
if has_controlling_tty; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
@@ -1152,7 +1162,7 @@ is_promptable() {
|
||||
if [[ "$NO_PROMPT" == "1" ]]; then
|
||||
return 1
|
||||
fi
|
||||
if [[ -r /dev/tty && -w /dev/tty ]]; then
|
||||
if has_controlling_tty; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
@@ -2577,7 +2587,7 @@ run_bootstrap_onboarding_if_needed() {
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ! -r /dev/tty || ! -w /dev/tty ]]; then
|
||||
if ! is_promptable; then
|
||||
local user_claw
|
||||
user_claw="$(openclaw_command_for_user "${OPENCLAW_BIN:-}")"
|
||||
ui_info "BOOTSTRAP.md found but no TTY; run ${user_claw} onboard to finish setup"
|
||||
@@ -2962,7 +2972,7 @@ main() {
|
||||
ui_kv "Switch to npm" "curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method npm"
|
||||
elif [[ "$is_upgrade" == "true" ]]; then
|
||||
ui_info "Upgrade complete"
|
||||
if [[ -r /dev/tty && -w /dev/tty ]]; then
|
||||
if has_controlling_tty || [[ "$NO_ONBOARD" == "1" || "$NO_PROMPT" == "1" ]]; then
|
||||
local claw="${OPENCLAW_BIN:-}"
|
||||
if [[ -z "$claw" ]]; then
|
||||
claw="$(resolve_openclaw_bin || true)"
|
||||
@@ -3010,7 +3020,7 @@ main() {
|
||||
fi
|
||||
ui_info "Starting setup"
|
||||
echo ""
|
||||
if [[ -r /dev/tty && -w /dev/tty ]]; then
|
||||
if is_promptable; then
|
||||
local claw="${OPENCLAW_BIN:-}"
|
||||
if [[ -z "$claw" ]]; then
|
||||
claw="$(resolve_openclaw_bin || true)"
|
||||
|
||||
@@ -431,6 +431,19 @@ describe("install.sh", () => {
|
||||
expect(script).toContain('corepack prepare "pnpm@${version}" --activate');
|
||||
expect(script).toContain('activate_repo_pnpm_version "$repo_dir"');
|
||||
});
|
||||
|
||||
it("does not treat /dev/tty permissions as a controlling terminal", () => {
|
||||
const result = runInstallShell(`
|
||||
set -euo pipefail
|
||||
source "${SCRIPT_PATH}"
|
||||
if has_controlling_tty; then echo "has_tty=1"; else echo "has_tty=0"; fi
|
||||
if is_promptable; then echo "promptable=1"; else echo "promptable=0"; fi
|
||||
`);
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout).toContain("has_tty=0");
|
||||
expect(result.stdout).toContain("promptable=0");
|
||||
});
|
||||
});
|
||||
|
||||
describe("install.sh macOS Homebrew Node behavior", () => {
|
||||
|
||||
@@ -23,7 +23,8 @@ describe("website installer sync workflow", () => {
|
||||
it("verifies installers on Linux Docker plus native macOS and Windows runners", () => {
|
||||
expect(workflow).toContain("linux-docker:");
|
||||
expect(workflow).toContain("docker run --rm");
|
||||
expect(workflow).toContain("bash /tmp/install.sh --no-prompt --no-onboard");
|
||||
expect(workflow).toContain("bash /tmp/install.sh --version latest && openclaw --version");
|
||||
expect(workflow).not.toContain("bash /tmp/install.sh --no-prompt --no-onboard");
|
||||
expect(workflow).toContain("bash /tmp/install-cli.sh --prefix /tmp/openclaw");
|
||||
expect(workflow).toContain("macos-installer:");
|
||||
expect(workflow).toContain("runs-on: macos-latest");
|
||||
|
||||
Reference in New Issue
Block a user