From c44509b397b800a495a48c96941536bc979db7fa Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 17 Feb 2026 02:34:39 +0900 Subject: [PATCH] fix: skip startup toasts in CLI run mode for auto-update-checker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add OPENCODE_CLI_RUN_MODE environment variable check to skip all startup toasts and version checks when running in CLI mode. This prevents notification spam during automated CLI run sessions. Includes comprehensive test coverage for CLI run mode behavior. 🤖 Generated with OhMyOpenCode assistance --- src/hooks/auto-update-checker/hook.test.ts | 83 ++++++++++++++++++++++ src/hooks/auto-update-checker/hook.ts | 2 + 2 files changed, 85 insertions(+) create mode 100644 src/hooks/auto-update-checker/hook.test.ts diff --git a/src/hooks/auto-update-checker/hook.test.ts b/src/hooks/auto-update-checker/hook.test.ts new file mode 100644 index 00000000..8cd1200a --- /dev/null +++ b/src/hooks/auto-update-checker/hook.test.ts @@ -0,0 +1,83 @@ +import { describe, it, expect, mock } from "bun:test" + +const mockShowConfigErrorsIfAny = mock(async () => {}) +const mockShowModelCacheWarningIfNeeded = mock(async () => {}) +const mockUpdateAndShowConnectedProvidersCacheStatus = mock(async () => {}) +const mockShowLocalDevToast = mock(async () => {}) +const mockShowVersionToast = mock(async () => {}) +const mockRunBackgroundUpdateCheck = mock(async () => {}) +const mockGetCachedVersion = mock(() => "3.6.0") +const mockGetLocalDevVersion = mock(() => "3.6.0") + +mock.module("./hook/config-errors-toast", () => ({ + showConfigErrorsIfAny: mockShowConfigErrorsIfAny, +})) + +mock.module("./hook/model-cache-warning", () => ({ + showModelCacheWarningIfNeeded: mockShowModelCacheWarningIfNeeded, +})) + +mock.module("./hook/connected-providers-status", () => ({ + updateAndShowConnectedProvidersCacheStatus: + mockUpdateAndShowConnectedProvidersCacheStatus, +})) + +mock.module("./hook/startup-toasts", () => ({ + showLocalDevToast: mockShowLocalDevToast, + showVersionToast: mockShowVersionToast, +})) + +mock.module("./hook/background-update-check", () => ({ + runBackgroundUpdateCheck: mockRunBackgroundUpdateCheck, +})) + +mock.module("./checker", () => ({ + getCachedVersion: mockGetCachedVersion, + getLocalDevVersion: mockGetLocalDevVersion, +})) + +mock.module("../../shared/logger", () => ({ + log: () => {}, +})) + +const { createAutoUpdateCheckerHook } = await import("./hook") + +describe("createAutoUpdateCheckerHook", () => { + it("skips startup toasts and checks in CLI run mode", async () => { + //#given - CLI run mode enabled + process.env.OPENCODE_CLI_RUN_MODE = "true" + mockShowConfigErrorsIfAny.mockClear() + mockShowModelCacheWarningIfNeeded.mockClear() + mockUpdateAndShowConnectedProvidersCacheStatus.mockClear() + mockShowLocalDevToast.mockClear() + mockShowVersionToast.mockClear() + mockRunBackgroundUpdateCheck.mockClear() + + const hook = createAutoUpdateCheckerHook( + { + directory: "/test", + client: {} as never, + } as never, + { showStartupToast: true, isSisyphusEnabled: true, autoUpdate: true } + ) + + //#when - session.created event arrives + hook.event({ + event: { + type: "session.created", + properties: { info: { parentID: undefined } }, + }, + }) + await new Promise((resolve) => setTimeout(resolve, 25)) + + //#then - no update checker side effects run + expect(mockShowConfigErrorsIfAny).not.toHaveBeenCalled() + expect(mockShowModelCacheWarningIfNeeded).not.toHaveBeenCalled() + expect(mockUpdateAndShowConnectedProvidersCacheStatus).not.toHaveBeenCalled() + expect(mockShowLocalDevToast).not.toHaveBeenCalled() + expect(mockShowVersionToast).not.toHaveBeenCalled() + expect(mockRunBackgroundUpdateCheck).not.toHaveBeenCalled() + + delete process.env.OPENCODE_CLI_RUN_MODE + }) +}) diff --git a/src/hooks/auto-update-checker/hook.ts b/src/hooks/auto-update-checker/hook.ts index 64513b6f..e0a2eaa8 100644 --- a/src/hooks/auto-update-checker/hook.ts +++ b/src/hooks/auto-update-checker/hook.ts @@ -10,6 +10,7 @@ import { showLocalDevToast, showVersionToast } from "./hook/startup-toasts" export function createAutoUpdateCheckerHook(ctx: PluginInput, options: AutoUpdateCheckerOptions = {}) { const { showStartupToast = true, isSisyphusEnabled = false, autoUpdate = true } = options + const isCliRunMode = process.env.OPENCODE_CLI_RUN_MODE === "true" const getToastMessage = (isUpdate: boolean, latestVersion?: string): string => { if (isSisyphusEnabled) { @@ -27,6 +28,7 @@ export function createAutoUpdateCheckerHook(ctx: PluginInput, options: AutoUpdat return { event: ({ event }: { event: { type: string; properties?: unknown } }) => { if (event.type !== "session.created") return + if (isCliRunMode) return if (hasChecked) return const props = event.properties as { info?: { parentID?: string } } | undefined