Merge pull request #791 from roshanasingh4/fix/788-implicit-delivery-leak
Prevent onboarding TUI from auto-delivering to lastProvider/lastTo
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
- Google: apply patched pi-ai `google-gemini-cli` function call handling (strips ids) after upgrading to pi-ai 0.43.0.
|
||||
- Auto-reply: elevated/reasoning toggles now enqueue system events so the model sees the mode change immediately.
|
||||
- Tools: keep `image` available in sandbox and fail over when image models return empty output (fixes “(no text returned)”).
|
||||
- Onboarding: TUI defaults to `deliver: false` to avoid cross-provider auto-delivery leaks; onboarding spawns the TUI with explicit `deliver: false`. (#791 — thanks @roshanasingh4)
|
||||
|
||||
## 2026.1.11
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ import {
|
||||
agentsDeleteCommand,
|
||||
agentsListCommand,
|
||||
} from "../commands/agents.js";
|
||||
import { dashboardCommand } from "../commands/dashboard.js";
|
||||
import {
|
||||
CONFIGURE_WIZARD_SECTIONS,
|
||||
configureCommand,
|
||||
configureCommandWithSections,
|
||||
} from "../commands/configure.js";
|
||||
import { dashboardCommand } from "../commands/dashboard.js";
|
||||
import { doctorCommand } from "../commands/doctor.js";
|
||||
import { healthCommand } from "../commands/health.js";
|
||||
import { messageCommand } from "../commands/message.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it, vi, beforeEach } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { dashboardCommand } from "./dashboard.js";
|
||||
|
||||
@@ -94,7 +94,10 @@ describe("dashboardCommand", () => {
|
||||
it("prints SSH hint when browser cannot open", async () => {
|
||||
mockSnapshot("shhhh");
|
||||
mocks.copyToClipboard.mockResolvedValue(false);
|
||||
mocks.detectBrowserOpenSupport.mockResolvedValue({ ok: false, reason: "ssh" });
|
||||
mocks.detectBrowserOpenSupport.mockResolvedValue({
|
||||
ok: false,
|
||||
reason: "ssh",
|
||||
});
|
||||
mocks.formatControlUiSshHint.mockReturnValue("ssh hint");
|
||||
|
||||
await dashboardCommand(runtime);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { resolveGatewayPort, readConfigFileSnapshot } from "../config/config.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import {
|
||||
readConfigFileSnapshot,
|
||||
resolveGatewayPort,
|
||||
} from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import {
|
||||
copyToClipboard,
|
||||
detectBrowserOpenSupport,
|
||||
@@ -33,7 +36,9 @@ export async function dashboardCommand(
|
||||
runtime.log(`Dashboard URL: ${authedUrl}`);
|
||||
|
||||
const copied = await copyToClipboard(authedUrl).catch(() => false);
|
||||
runtime.log(copied ? "Copied to clipboard." : "Copy to clipboard unavailable.");
|
||||
runtime.log(
|
||||
copied ? "Copied to clipboard." : "Copy to clipboard unavailable.",
|
||||
);
|
||||
|
||||
let opened = false;
|
||||
let hint: string | undefined;
|
||||
|
||||
@@ -199,7 +199,7 @@ export async function runTui(opts: TuiOptions) {
|
||||
let isConnected = false;
|
||||
let toolsExpanded = false;
|
||||
let showThinking = false;
|
||||
const deliverDefault = opts.deliver ?? true;
|
||||
const deliverDefault = opts.deliver ?? false;
|
||||
const autoMessage = opts.message?.trim();
|
||||
let autoMessageSent = false;
|
||||
let sessionInfo: SessionInfo = {};
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { DEFAULT_BOOTSTRAP_FILENAME } from "../agents/workspace.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { runOnboardingWizard } from "./onboarding.js";
|
||||
import type { WizardPrompter } from "./prompts.js";
|
||||
@@ -117,4 +121,64 @@ describe("runOnboardingWizard", () => {
|
||||
expect(healthCommand).not.toHaveBeenCalled();
|
||||
expect(runTui).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("launches TUI without auto-delivery when hatching", async () => {
|
||||
runTui.mockClear();
|
||||
|
||||
const workspaceDir = await fs.mkdtemp(
|
||||
path.join(os.tmpdir(), "clawdbot-onboard-"),
|
||||
);
|
||||
await fs.writeFile(
|
||||
path.join(workspaceDir, DEFAULT_BOOTSTRAP_FILENAME),
|
||||
"{}",
|
||||
);
|
||||
|
||||
const confirm: WizardPrompter["confirm"] = vi.fn(async (opts) => {
|
||||
if (opts.message === "Do you want to hatch your bot now?") return true;
|
||||
return opts.initialValue ?? false;
|
||||
});
|
||||
|
||||
const prompter: WizardPrompter = {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: vi.fn(async () => "quickstart"),
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => ""),
|
||||
confirm,
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
};
|
||||
|
||||
const runtime: RuntimeEnv = {
|
||||
log: vi.fn(),
|
||||
error: vi.fn(),
|
||||
exit: vi.fn((code: number) => {
|
||||
throw new Error(`exit:${code}`);
|
||||
}),
|
||||
};
|
||||
|
||||
await runOnboardingWizard(
|
||||
{
|
||||
flow: "quickstart",
|
||||
mode: "local",
|
||||
workspace: workspaceDir,
|
||||
authChoice: "skip",
|
||||
skipProviders: true,
|
||||
skipSkills: true,
|
||||
skipHealth: true,
|
||||
installDaemon: false,
|
||||
},
|
||||
runtime,
|
||||
prompter,
|
||||
);
|
||||
|
||||
expect(runTui).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
deliver: false,
|
||||
message: "Wake up, my friend!",
|
||||
}),
|
||||
);
|
||||
|
||||
await fs.rm(workspaceDir, { recursive: true, force: true });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -796,6 +796,8 @@ export async function runOnboardingWizard(
|
||||
token: authMode === "token" ? gatewayToken : undefined,
|
||||
password:
|
||||
authMode === "password" ? baseConfig.gateway?.auth?.password : "",
|
||||
// Safety: onboarding TUI should not auto-deliver to lastProvider/lastTo.
|
||||
deliver: false,
|
||||
message: "Wake up, my friend!",
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user