diff --git a/src/cli/acp-cli.option-collisions.test.ts b/src/cli/acp-cli.option-collisions.test.ts index 068f415de79..820467ba5a4 100644 --- a/src/cli/acp-cli.option-collisions.test.ts +++ b/src/cli/acp-cli.option-collisions.test.ts @@ -7,7 +7,10 @@ const runAcpClientInteractive = vi.fn(async (_opts: unknown) => {}); const serveAcpGateway = vi.fn(async (_opts: unknown) => {}); const defaultRuntime = { + log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn(), + writeJson: vi.fn(), exit: vi.fn(), }; @@ -52,7 +55,10 @@ describe("acp cli option collisions", () => { beforeEach(() => { runAcpClientInteractive.mockClear(); serveAcpGateway.mockClear(); + defaultRuntime.log.mockClear(); defaultRuntime.error.mockClear(); + defaultRuntime.writeStdout.mockClear(); + defaultRuntime.writeJson.mockClear(); defaultRuntime.exit.mockClear(); }); diff --git a/src/cli/browser-cli-inspect.test.ts b/src/cli/browser-cli-inspect.test.ts index 14a0b2f3be9..a58d83614a4 100644 --- a/src/cli/browser-cli-inspect.test.ts +++ b/src/cli/browser-cli-inspect.test.ts @@ -50,6 +50,12 @@ vi.mock("./browser-cli-shared.js", () => ({ const runtime = { log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn((value: string) => { + runtime.log(value.endsWith("\n") ? value.slice(0, -1) : value); + }), + writeJson: vi.fn((value: unknown, space = 2) => { + runtime.log(JSON.stringify(value, null, space)); + }), exit: vi.fn(), }; vi.mock("../runtime.js", () => ({ diff --git a/src/cli/browser-cli-manage.test.ts b/src/cli/browser-cli-manage.test.ts index 86c10ac75ae..c4d7a36ffa3 100644 --- a/src/cli/browser-cli-manage.test.ts +++ b/src/cli/browser-cli-manage.test.ts @@ -20,6 +20,12 @@ const mocks = vi.hoisted(() => { runtime: { log: runtimeLog, error: runtimeError, + writeStdout: vi.fn((value: string) => + runtimeLog(value.endsWith("\n") ? value.slice(0, -1) : value), + ), + writeJson: vi.fn((value: unknown, space = 2) => + runtimeLog(JSON.stringify(value, null, space)), + ), exit: runtimeExit, }, }; diff --git a/src/cli/browser-cli-manage.timeout-option.test.ts b/src/cli/browser-cli-manage.timeout-option.test.ts index 7338d97701e..d52341a37da 100644 --- a/src/cli/browser-cli-manage.timeout-option.test.ts +++ b/src/cli/browser-cli-manage.timeout-option.test.ts @@ -28,6 +28,12 @@ const mocks = vi.hoisted(() => { runtime: { log: runtimeLog, error: runtimeError, + writeStdout: vi.fn((value: string) => + runtimeLog(value.endsWith("\n") ? value.slice(0, -1) : value), + ), + writeJson: vi.fn((value: unknown, space = 2) => + runtimeLog(JSON.stringify(value, null, space)), + ), exit: runtimeExit, }, }; diff --git a/src/cli/browser-cli-state.option-collisions.test.ts b/src/cli/browser-cli-state.option-collisions.test.ts index 2fb445c6af7..4980abc2993 100644 --- a/src/cli/browser-cli-state.option-collisions.test.ts +++ b/src/cli/browser-cli-state.option-collisions.test.ts @@ -8,6 +8,12 @@ const mocks = vi.hoisted(() => ({ runtime: { log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn((value: string) => { + mocks.runtime.log(value.endsWith("\n") ? value.slice(0, -1) : value); + }), + writeJson: vi.fn((value: unknown, space = 2) => { + mocks.runtime.log(JSON.stringify(value, null, space)); + }), exit: vi.fn(), }, })); @@ -55,6 +61,8 @@ describe("browser state option collisions", () => { mocks.runBrowserResizeWithOutput.mockClear(); mocks.runtime.log.mockClear(); mocks.runtime.error.mockClear(); + mocks.runtime.writeStdout.mockClear(); + mocks.runtime.writeJson.mockClear(); mocks.runtime.exit.mockClear(); }); diff --git a/src/cli/config-cli.test.ts b/src/cli/config-cli.test.ts index 954dbdc3d51..9a699856575 100644 --- a/src/cli/config-cli.test.ts +++ b/src/cli/config-cli.test.ts @@ -41,6 +41,7 @@ vi.mock("../runtime.js", async (importOriginal) => { defaultRuntime: { log: (...args: unknown[]) => mockLog(...args), error: (...args: unknown[]) => mockError(...args), + writeStdout: (value: string) => mockLog(value.endsWith("\n") ? value.slice(0, -1) : value), writeJson: (value: unknown, space = 2) => mockLog(JSON.stringify(value, null, space > 0 ? space : undefined)), exit: (code: number) => mockExit(code), diff --git a/src/cli/cron-cli.test.ts b/src/cli/cron-cli.test.ts index ca4ccd0472f..4988af09a1a 100644 --- a/src/cli/cron-cli.test.ts +++ b/src/cli/cron-cli.test.ts @@ -29,6 +29,7 @@ vi.mock("../runtime.js", () => ({ defaultRuntime: { log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn(), writeJson: vi.fn(), exit: (code: number) => { throw new Error(`__exit__:${code}`); diff --git a/src/cli/daemon-cli/install.integration.test.ts b/src/cli/daemon-cli/install.integration.test.ts index db6df6a429e..52272b61f55 100644 --- a/src/cli/daemon-cli/install.integration.test.ts +++ b/src/cli/daemon-cli/install.integration.test.ts @@ -28,8 +28,12 @@ vi.mock("../../runtime.js", () => ({ defaultRuntime: { log: (message: string) => runtimeLogs.push(message), error: (message: string) => runtimeErrors.push(message), - writeJson: (value: unknown, space = 2) => - runtimeLogs.push(JSON.stringify(value, null, space > 0 ? space : undefined)), + writeStdout: (value: string) => { + runtimeLogs.push(value.endsWith("\n") ? value.slice(0, -1) : value); + }, + writeJson: (value: unknown, space = 2) => { + runtimeLogs.push(JSON.stringify(value, null, space > 0 ? space : undefined)); + }, exit: (code: number) => { throw new Error(`__exit__:${code}`); }, diff --git a/src/cli/daemon-cli/install.test.ts b/src/cli/daemon-cli/install.test.ts index 500e2bf9aaf..ddb95a8cdf6 100644 --- a/src/cli/daemon-cli/install.test.ts +++ b/src/cli/daemon-cli/install.test.ts @@ -129,6 +129,12 @@ const runtimeLogs: string[] = []; vi.mock("../../runtime.js", () => ({ defaultRuntime: { log: (message: string) => runtimeLogs.push(message), + writeStdout: (value: string) => { + runtimeLogs.push(value.endsWith("\n") ? value.slice(0, -1) : value); + }, + writeJson: (value: unknown, space = 2) => { + runtimeLogs.push(JSON.stringify(value, null, space)); + }, error: vi.fn(), exit: vi.fn(), }, diff --git a/src/cli/daemon-cli/test-helpers/lifecycle-core-harness.ts b/src/cli/daemon-cli/test-helpers/lifecycle-core-harness.ts index 989f254d962..84e3611b6da 100644 --- a/src/cli/daemon-cli/test-helpers/lifecycle-core-harness.ts +++ b/src/cli/daemon-cli/test-helpers/lifecycle-core-harness.ts @@ -8,6 +8,8 @@ export const runtimeLogs: string[] = []; type LifecycleRuntimeHarness = OutputRuntimeEnv & { error: MockFn; exit: MockFn; + writeStdout: MockFn<(value: string) => void>; + writeJson: MockFn<(value: unknown, space?: number) => void>; }; type LifecycleServiceHarness = GatewayService & { @@ -24,13 +26,13 @@ export const defaultRuntime: LifecycleRuntimeHarness = { log: (...args: unknown[]) => { runtimeLogs.push(args.map((arg) => String(arg)).join(" ")); }, - writeStdout: (value: string) => { - runtimeLogs.push(value); - }, - writeJson: (value: unknown, space = 2) => { - runtimeLogs.push(JSON.stringify(value, null, space > 0 ? space : undefined)); - }, error: vi.fn(), + writeStdout: vi.fn((value: string) => { + runtimeLogs.push(value.endsWith("\n") ? value.slice(0, -1) : value); + }), + writeJson: vi.fn((value: unknown, space = 2) => { + runtimeLogs.push(JSON.stringify(value, null, space > 0 ? space : undefined)); + }), exit: vi.fn((code: number) => { throw new Error(`__exit__:${code}`); }), diff --git a/src/cli/devices-cli.test.ts b/src/cli/devices-cli.test.ts index b5882c3129c..bf3627fc72e 100644 --- a/src/cli/devices-cli.test.ts +++ b/src/cli/devices-cli.test.ts @@ -14,7 +14,12 @@ const withProgress = vi.fn(async (_opts: unknown, fn: () => Promise) => const runtime = { log: vi.fn(), error: vi.fn(), - writeJson: vi.fn(), + writeStdout: vi.fn((value: string) => { + runtime.log(value.endsWith("\n") ? value.slice(0, -1) : value); + }), + writeJson: vi.fn((value: unknown, space = 2) => { + runtime.log(JSON.stringify(value, null, space > 0 ? space : undefined)); + }), exit: vi.fn(), }; diff --git a/src/cli/directory-cli.test.ts b/src/cli/directory-cli.test.ts index 4e11a0f648d..7247dd853b1 100644 --- a/src/cli/directory-cli.test.ts +++ b/src/cli/directory-cli.test.ts @@ -42,6 +42,8 @@ vi.mock("../runtime.js", () => ({ writeJson: (value: unknown, space = 2) => mocks.log(JSON.stringify(value, null, space > 0 ? space : undefined)), exit: (...args: unknown[]) => mocks.exit(...args), + writeStdout: (value: string) => mocks.log(value.endsWith("\n") ? value.slice(0, -1) : value), + writeJson: (value: unknown, space = 2) => mocks.log(JSON.stringify(value, null, space)), }, })); diff --git a/src/cli/mcp-cli.test.ts b/src/cli/mcp-cli.test.ts index 1a1077f1c08..eb2f0fbdb73 100644 --- a/src/cli/mcp-cli.test.ts +++ b/src/cli/mcp-cli.test.ts @@ -15,6 +15,7 @@ vi.mock("../runtime.js", () => ({ defaultRuntime: { log: (...args: unknown[]) => mockLog(...args), error: (...args: unknown[]) => mockError(...args), + writeStdout: (value: string) => mockLog(value.endsWith("\n") ? value.slice(0, -1) : value), writeJson: (value: unknown, space = 2) => mockLog(JSON.stringify(value, null, space > 0 ? space : undefined)), exit: (code: number) => mockExit(code), diff --git a/src/cli/program/register.agent.test.ts b/src/cli/program/register.agent.test.ts index 1085c33fa21..1586bb355a9 100644 --- a/src/cli/program/register.agent.test.ts +++ b/src/cli/program/register.agent.test.ts @@ -15,6 +15,12 @@ const createDefaultDepsMock = vi.fn(() => ({ deps: true })); const runtime = { log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn((value: string) => { + runtime.log(value.endsWith("\n") ? value.slice(0, -1) : value); + }), + writeJson: vi.fn((value: unknown, space = 2) => { + runtime.log(JSON.stringify(value, null, space)); + }), exit: vi.fn(), }; diff --git a/src/cli/program/register.backup.test.ts b/src/cli/program/register.backup.test.ts index f2d8dc95f11..c1b224b6d65 100644 --- a/src/cli/program/register.backup.test.ts +++ b/src/cli/program/register.backup.test.ts @@ -7,6 +7,12 @@ const backupVerifyCommand = vi.fn(); const runtime = { log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn((value: string) => { + runtime.log(value.endsWith("\n") ? value.slice(0, -1) : value); + }), + writeJson: vi.fn((value: unknown, space = 2) => { + runtime.log(JSON.stringify(value, null, space)); + }), exit: vi.fn(), }; diff --git a/src/cli/program/register.status-health-sessions.test.ts b/src/cli/program/register.status-health-sessions.test.ts index 5a45b4d293a..86cbe1869ee 100644 --- a/src/cli/program/register.status-health-sessions.test.ts +++ b/src/cli/program/register.status-health-sessions.test.ts @@ -10,6 +10,12 @@ const setVerbose = vi.fn(); const runtime = { log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn((value: string) => { + runtime.log(value.endsWith("\n") ? value.slice(0, -1) : value); + }), + writeJson: vi.fn((value: unknown, space = 2) => { + runtime.log(JSON.stringify(value, null, space)); + }), exit: vi.fn(), }; diff --git a/src/cli/qr-cli.test.ts b/src/cli/qr-cli.test.ts index 8d984c857ff..c7d54a6247a 100644 --- a/src/cli/qr-cli.test.ts +++ b/src/cli/qr-cli.test.ts @@ -6,6 +6,9 @@ const mocks = vi.hoisted(() => ({ runtime: { log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn((value: string) => { + mocks.runtime.log(value.endsWith("\n") ? value.slice(0, -1) : value); + }), writeJson: vi.fn((value: unknown, space = 2) => { mocks.runtime.log(JSON.stringify(value, null, space > 0 ? space : undefined)); }), diff --git a/src/cli/route.test.ts b/src/cli/route.test.ts index 9e7c6c7c110..a335f4f56e9 100644 --- a/src/cli/route.test.ts +++ b/src/cli/route.test.ts @@ -23,7 +23,13 @@ vi.mock("./program/routes.js", () => ({ })); vi.mock("../runtime.js", () => ({ - defaultRuntime: { error: vi.fn(), log: vi.fn(), exit: vi.fn() }, + defaultRuntime: { + error: vi.fn(), + log: vi.fn(), + writeStdout: vi.fn(), + writeJson: vi.fn(), + exit: vi.fn(), + }, })); describe("tryRouteCli", () => { diff --git a/src/cli/test-runtime-capture.ts b/src/cli/test-runtime-capture.ts index ddd9a0db047..6ff5df0b0de 100644 --- a/src/cli/test-runtime-capture.ts +++ b/src/cli/test-runtime-capture.ts @@ -22,7 +22,7 @@ export function createCliRuntimeCapture(): CliRuntimeCapture { runtimeErrors.push(stringifyArgs(args)); }, writeStdout: (value: string) => { - runtimeLogs.push(value); + runtimeLogs.push(value.endsWith("\n") ? value.slice(0, -1) : value); }, writeJson: (value: unknown, space = 2) => { runtimeLogs.push(JSON.stringify(value, null, space > 0 ? space : undefined)); diff --git a/src/cli/update-cli.option-collisions.test.ts b/src/cli/update-cli.option-collisions.test.ts index 6db4cfdd260..e38b38184aa 100644 --- a/src/cli/update-cli.option-collisions.test.ts +++ b/src/cli/update-cli.option-collisions.test.ts @@ -9,6 +9,12 @@ const updateWizardCommand = vi.fn(async (_opts: unknown) => {}); const defaultRuntime = { log: vi.fn(), error: vi.fn(), + writeStdout: vi.fn((value: string) => { + defaultRuntime.log(value.endsWith("\n") ? value.slice(0, -1) : value); + }), + writeJson: vi.fn((value: unknown, space = 2) => { + defaultRuntime.log(JSON.stringify(value, null, space)); + }), exit: vi.fn(), }; @@ -41,6 +47,8 @@ describe("update cli option collisions", () => { updateWizardCommand.mockClear(); defaultRuntime.log.mockClear(); defaultRuntime.error.mockClear(); + defaultRuntime.writeStdout.mockClear(); + defaultRuntime.writeJson.mockClear(); defaultRuntime.exit.mockClear(); }); diff --git a/src/cli/update-cli.test.ts b/src/cli/update-cli.test.ts index 4781137fad5..b38e2c4075f 100644 --- a/src/cli/update-cli.test.ts +++ b/src/cli/update-cli.test.ts @@ -139,6 +139,9 @@ vi.mock("../runtime.js", () => ({ defaultRuntime: { log: runtimeLog, error: runtimeError, + writeStdout: vi.fn((value: string) => + runtimeLog(value.endsWith("\n") ? value.slice(0, -1) : value), + ), writeJson: runtimeWriteJson, exit: runtimeExit, },