diff --git a/packages/cli/package.json b/packages/cli/package.json index a5e35832..657b6a6f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openrouter/spawn", - "version": "0.17.16", + "version": "0.17.17", "type": "module", "bin": { "spawn": "cli.js" diff --git a/packages/cli/src/commands/interactive.ts b/packages/cli/src/commands/interactive.ts index 6f65373e..b70e7aff 100644 --- a/packages/cli/src/commands/interactive.ts +++ b/packages/cli/src/commands/interactive.ts @@ -176,12 +176,15 @@ async function promptSetupOptions(agentName: string): Promise | unde // 1. Arrow keys work immediately (multiple items to navigate) // 2. Users can explicitly skip all steps without pressing Enter on an empty list // 3. Users who accidentally select another option can deselect it and choose None - const hasBrowserDefault = filteredSteps.some((s) => s.value === "browser"); - const defaultValues = hasBrowserDefault - ? filteredSteps.filter((s) => s.value === "browser").map((s) => s.value) - : [ - NONE_STEP, - ]; + // Pre-select browser + telegram by default (telegram has the smoothest setup UX) + const recommendedDefaults = [ + "browser", + "telegram", + ]; + const defaultValues = filteredSteps.filter((s) => recommendedDefaults.includes(s.value)).map((s) => s.value); + if (defaultValues.length === 0) { + defaultValues.push(NONE_STEP); + } const selected = await p.multiselect({ message: "Setup options (↑/↓ navigate, space to select, enter to confirm)", diff --git a/packages/cli/src/shared/agent-setup.ts b/packages/cli/src/shared/agent-setup.ts index d475b23e..214c3793 100644 --- a/packages/cli/src/shared/agent-setup.ts +++ b/packages/cli/src/shared/agent-setup.ts @@ -374,6 +374,7 @@ async function setupOpenclawConfig( enabled: true, botToken: telegramBotToken, dmPolicy: "pairing", + groupPolicy: "open", groups: { "*": { requireMention: true, @@ -386,7 +387,7 @@ async function setupOpenclawConfig( if (enabledSteps?.has("whatsapp")) { channels.whatsapp = { dmPolicy: "pairing", - groupPolicy: "allowlist", + groupPolicy: "open", sendReadReceipts: true, }; } @@ -399,14 +400,14 @@ async function setupOpenclawConfig( await uploadConfigFile(runner, config, "$HOME/.openclaw/openclaw.json"); // Configure browser via CLI (openclaw config set) — the supported way to set - // browser options. Writing JSON directly may not be picked up by all versions. + // browser options. Redirect stdout to suppress doctor warnings on each call. const browserResult = await asyncTryCatchIf(isOperationalError, () => runner.runServer( "export PATH=$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; " + - "openclaw config set browser.executablePath /usr/bin/google-chrome-stable; " + - "openclaw config set browser.noSandbox true; " + - "openclaw config set browser.headless true; " + - "openclaw config set browser.defaultProfile openclaw", + "openclaw config set browser.executablePath /usr/bin/google-chrome-stable >/dev/null; " + + "openclaw config set browser.noSandbox true >/dev/null; " + + "openclaw config set browser.headless true >/dev/null; " + + "openclaw config set browser.defaultProfile openclaw >/dev/null", ), ); if (!browserResult.ok) { @@ -419,7 +420,7 @@ async function setupOpenclawConfig( const gatewayTokenResult = await asyncTryCatchIf(isOperationalError, () => runner.runServer( "export PATH=$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; " + - `openclaw config set gateway.auth.token ${shellQuote(gatewayToken)}`, + `openclaw config set gateway.auth.token ${shellQuote(gatewayToken)} >/dev/null`, ), ); if (!gatewayTokenResult.ok) { diff --git a/packages/cli/src/shared/agents.ts b/packages/cli/src/shared/agents.ts index 7ea1d67b..0113a20b 100644 --- a/packages/cli/src/shared/agents.ts +++ b/packages/cli/src/shared/agents.ts @@ -63,7 +63,7 @@ const AGENT_EXTRA_STEPS: Record = { { value: "telegram", label: "Telegram", - hint: "connect via bot token from @BotFather", + hint: "recommended — connect via bot token from @BotFather", dataEnvVar: "TELEGRAM_BOT_TOKEN", }, { diff --git a/packages/cli/src/shared/orchestrate.ts b/packages/cli/src/shared/orchestrate.ts index 949f6968..1192b79c 100644 --- a/packages/cli/src/shared/orchestrate.ts +++ b/packages/cli/src/shared/orchestrate.ts @@ -298,8 +298,12 @@ export async function runOrchestration( if (enabledSteps?.has("telegram")) { logStep("Telegram pairing..."); - logInfo("DM your Telegram bot to get a pairing code, then enter it below."); - logInfo("Waiting for pairing code..."); + logInfo("To pair your Telegram account:"); + logInfo(" 1. Open Telegram on your phone"); + logInfo(" 2. Search for the bot you created with @BotFather"); + logInfo(' 3. Send it any message (e.g. "hello")'); + logInfo(" 4. The bot will reply with a pairing code"); + logInfo(" 5. Enter the code below"); process.stderr.write("\n"); const pairingCode = (await prompt("Telegram pairing code: ")).trim(); if (pairingCode) { @@ -320,34 +324,16 @@ export async function runOrchestration( } if (enabledSteps?.has("whatsapp")) { - // Step 1: QR code scan to link the WhatsApp device logStep("Linking WhatsApp — scan the QR code with your phone..."); logInfo("Open WhatsApp > Settings > Linked Devices > Link a Device"); process.stderr.write("\n"); const whatsappCmd = `source ~/.spawnrc 2>/dev/null; ${ocPath}; openclaw channels login --channel whatsapp`; prepareStdinForHandoff(); await cloud.interactiveSession(whatsappCmd); - - // Step 2: Pairing — approve your own number so the bot responds to you - logStep("WhatsApp pairing..."); - logInfo("Send a message to your bot on WhatsApp to get a pairing code, then enter it below."); - process.stderr.write("\n"); - const pairingCode = (await prompt("WhatsApp pairing code: ")).trim(); - if (pairingCode) { - const escaped = shellQuote(pairingCode); - const result = await asyncTryCatchIf(isOperationalError, () => - cloud.runner.runServer( - `source ~/.spawnrc 2>/dev/null; ${ocPath}; openclaw pairing approve whatsapp ${escaped}`, - ), - ); - if (result.ok) { - logInfo("WhatsApp paired successfully"); - } else { - logWarn("Pairing failed — you can pair later via: openclaw pairing approve whatsapp "); - } - } else { - logInfo("No code entered — pair later via: openclaw pairing approve whatsapp "); - } + logInfo("WhatsApp linked! To pair a contact:"); + logInfo(" 1. Have someone message your WhatsApp number"); + logInfo(" 2. They'll get a pairing code from the bot"); + logInfo(" 3. Approve via: openclaw pairing approve whatsapp "); } // 11d. Agent-specific pre-launch tip (e.g. channel setup ordering hint)