diff --git a/src/commands/configure.gateway.ts b/src/commands/configure.gateway.ts index 84db572eb2..b0676f311a 100644 --- a/src/commands/configure.gateway.ts +++ b/src/commands/configure.gateway.ts @@ -1,6 +1,11 @@ import type { OpenClawConfig } from "../config/config.js"; import type { RuntimeEnv } from "../runtime.js"; import { resolveGatewayPort } from "../config/config.js"; +import { + TAILSCALE_DOCS_LINES, + TAILSCALE_EXPOSURE_OPTIONS, + TAILSCALE_MISSING_BIN_NOTE_LINES, +} from "../gateway/gateway-config-prompts.shared.js"; import { findTailscaleBinary } from "../infra/tailscale.js"; import { validateIPv4AddressInput } from "../shared/net/ipv4.js"; import { note } from "../terminal/note.js"; @@ -100,19 +105,7 @@ export async function promptGatewayConfig( let tailscaleMode = guardCancel( await select({ message: "Tailscale exposure", - options: [ - { value: "off", label: "Off", hint: "No Tailscale exposure" }, - { - value: "serve", - label: "Serve", - hint: "Private HTTPS for your tailnet (devices on Tailscale)", - }, - { - value: "funnel", - label: "Funnel", - hint: "Public HTTPS via Tailscale Funnel (internet)", - }, - ], + options: [...TAILSCALE_EXPOSURE_OPTIONS], }), runtime, ); @@ -121,27 +114,13 @@ export async function promptGatewayConfig( if (tailscaleMode !== "off") { const tailscaleBin = await findTailscaleBinary(); if (!tailscaleBin) { - note( - [ - "Tailscale binary not found in PATH or /Applications.", - "Ensure Tailscale is installed from:", - " https://tailscale.com/download/mac", - "", - "You can continue setup, but serve/funnel will fail at runtime.", - ].join("\n"), - "Tailscale Warning", - ); + note(TAILSCALE_MISSING_BIN_NOTE_LINES.join("\n"), "Tailscale Warning"); } } let tailscaleResetOnExit = false; if (tailscaleMode !== "off") { - note( - ["Docs:", "https://docs.openclaw.ai/gateway/tailscale", "https://docs.openclaw.ai/web"].join( - "\n", - ), - "Tailscale", - ); + note(TAILSCALE_DOCS_LINES.join("\n"), "Tailscale"); tailscaleResetOnExit = Boolean( guardCancel( await confirm({ diff --git a/src/gateway/gateway-config-prompts.shared.ts b/src/gateway/gateway-config-prompts.shared.ts new file mode 100644 index 0000000000..e32d7ec0be --- /dev/null +++ b/src/gateway/gateway-config-prompts.shared.ts @@ -0,0 +1,27 @@ +export const TAILSCALE_EXPOSURE_OPTIONS = [ + { value: "off", label: "Off", hint: "No Tailscale exposure" }, + { + value: "serve", + label: "Serve", + hint: "Private HTTPS for your tailnet (devices on Tailscale)", + }, + { + value: "funnel", + label: "Funnel", + hint: "Public HTTPS via Tailscale Funnel (internet)", + }, +] as const; + +export const TAILSCALE_MISSING_BIN_NOTE_LINES = [ + "Tailscale binary not found in PATH or /Applications.", + "Ensure Tailscale is installed from:", + " https://tailscale.com/download/mac", + "", + "You can continue setup, but serve/funnel will fail at runtime.", +] as const; + +export const TAILSCALE_DOCS_LINES = [ + "Docs:", + "https://docs.openclaw.ai/gateway/tailscale", + "https://docs.openclaw.ai/web", +] as const; diff --git a/src/wizard/onboarding.gateway-config.ts b/src/wizard/onboarding.gateway-config.ts index dae687d12c..a874c077b2 100644 --- a/src/wizard/onboarding.gateway-config.ts +++ b/src/wizard/onboarding.gateway-config.ts @@ -12,6 +12,11 @@ import { randomToken, validateGatewayPasswordInput, } from "../commands/onboard-helpers.js"; +import { + TAILSCALE_DOCS_LINES, + TAILSCALE_EXPOSURE_OPTIONS, + TAILSCALE_MISSING_BIN_NOTE_LINES, +} from "../gateway/gateway-config-prompts.shared.js"; import { findTailscaleBinary } from "../infra/tailscale.js"; import { validateIPv4AddressInput } from "../shared/net/ipv4.js"; @@ -113,46 +118,20 @@ export async function configureGatewayForOnboarding( ? quickstartGateway.tailscaleMode : await prompter.select({ message: "Tailscale exposure", - options: [ - { value: "off", label: "Off", hint: "No Tailscale exposure" }, - { - value: "serve", - label: "Serve", - hint: "Private HTTPS for your tailnet (devices on Tailscale)", - }, - { - value: "funnel", - label: "Funnel", - hint: "Public HTTPS via Tailscale Funnel (internet)", - }, - ], + options: [...TAILSCALE_EXPOSURE_OPTIONS], }); // Detect Tailscale binary before proceeding with serve/funnel setup. if (tailscaleMode !== "off") { const tailscaleBin = await findTailscaleBinary(); if (!tailscaleBin) { - await prompter.note( - [ - "Tailscale binary not found in PATH or /Applications.", - "Ensure Tailscale is installed from:", - " https://tailscale.com/download/mac", - "", - "You can continue setup, but serve/funnel will fail at runtime.", - ].join("\n"), - "Tailscale Warning", - ); + await prompter.note(TAILSCALE_MISSING_BIN_NOTE_LINES.join("\n"), "Tailscale Warning"); } } let tailscaleResetOnExit = flow === "quickstart" ? quickstartGateway.tailscaleResetOnExit : false; if (tailscaleMode !== "off" && flow !== "quickstart") { - await prompter.note( - ["Docs:", "https://docs.openclaw.ai/gateway/tailscale", "https://docs.openclaw.ai/web"].join( - "\n", - ), - "Tailscale", - ); + await prompter.note(TAILSCALE_DOCS_LINES.join("\n"), "Tailscale"); tailscaleResetOnExit = Boolean( await prompter.confirm({ message: "Reset Tailscale serve/funnel on exit?",