From 4d236bf79b231c96268338f2e7c31676a25b4963 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:22:42 +0000 Subject: [PATCH 1/4] Initial plan From d10af27b0a43adc7ac7699441d51619f923552d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:30:34 +0000 Subject: [PATCH 2/4] Add platform to WaveEnv Co-authored-by: sawka <2722291+sawka@users.noreply.github.com> --- frontend/app/waveenv/waveenv.ts | 3 ++ frontend/app/waveenv/waveenvimpl.test.ts | 43 +++++++++++++++++++++++ frontend/app/waveenv/waveenvimpl.ts | 4 +++ frontend/preview/mock/mockwaveenv.test.ts | 32 +++++++++++++++++ frontend/preview/mock/mockwaveenv.ts | 13 ++++++- 5 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 frontend/app/waveenv/waveenvimpl.test.ts create mode 100644 frontend/preview/mock/mockwaveenv.test.ts diff --git a/frontend/app/waveenv/waveenv.ts b/frontend/app/waveenv/waveenv.ts index 365bf74be9..f643c24295 100644 --- a/frontend/app/waveenv/waveenv.ts +++ b/frontend/app/waveenv/waveenv.ts @@ -16,8 +16,11 @@ export type BlockMetaKeyAtomFnType export type WaveEnv = { electron: ElectronApi; rpc: RpcApiType; + platform: NodeJS.Platform; configAtoms: ConfigAtoms; isDev: () => boolean; + isWindows: () => boolean; + isMacOS: () => boolean; atoms: GlobalAtomsType; createBlock: (blockDef: BlockDef, magnified?: boolean, ephemeral?: boolean) => Promise; showContextMenu: (menu: ContextMenuItem[], e: React.MouseEvent) => void; diff --git a/frontend/app/waveenv/waveenvimpl.test.ts b/frontend/app/waveenv/waveenvimpl.test.ts new file mode 100644 index 0000000000..06991263ea --- /dev/null +++ b/frontend/app/waveenv/waveenvimpl.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it, vi } from "vitest"; + +describe("makeWaveEnvImpl", () => { + it("exposes platform helpers from platformutil", async () => { + const showContextMenu = vi.fn(); + const windowApi = { name: "electron-api" } as ElectronApi; + + vi.resetModules(); + vi.stubGlobal("window", { api: windowApi }); + vi.doMock("@/app/store/contextmenu", () => ({ + ContextMenuModel: { + getInstance: () => ({ + showContextMenu, + }), + }, + })); + vi.doMock("@/app/store/global", () => ({ + atoms: { workspace: "workspace-atom" }, + createBlock: vi.fn(), + getBlockMetaKeyAtom: vi.fn(), + getConnStatusAtom: vi.fn(), + getSettingsKeyAtom: vi.fn(), + isDev: vi.fn(() => true), + WOS: { getWaveObjectAtom: vi.fn() }, + })); + vi.doMock("@/app/store/wshclientapi", () => ({ + RpcApi: { name: "rpc-api" }, + })); + vi.doMock("@/util/platformutil", () => ({ + PLATFORM: "win32", + isWindows: vi.fn(() => true), + isMacOS: vi.fn(() => false), + })); + + const { makeWaveEnvImpl } = await import("./waveenvimpl"); + const env = makeWaveEnvImpl(); + + expect(env.electron).toBe(windowApi); + expect(env.platform).toBe("win32"); + expect(env.isWindows()).toBe(true); + expect(env.isMacOS()).toBe(false); + }); +}); diff --git a/frontend/app/waveenv/waveenvimpl.ts b/frontend/app/waveenv/waveenvimpl.ts index 50aa4ef7ea..0f2461fcf6 100644 --- a/frontend/app/waveenv/waveenvimpl.ts +++ b/frontend/app/waveenv/waveenvimpl.ts @@ -13,6 +13,7 @@ import { } from "@/app/store/global"; import { RpcApi } from "@/app/store/wshclientapi"; import { WaveEnv } from "@/app/waveenv/waveenv"; +import { isMacOS, isWindows, PLATFORM } from "@/util/platformutil"; const configAtoms = new Proxy({} as WaveEnv["configAtoms"], { get(_target: WaveEnv["configAtoms"], key: K) { @@ -24,8 +25,11 @@ export function makeWaveEnvImpl(): WaveEnv { return { electron: (window as any).api, rpc: RpcApi, + platform: PLATFORM, configAtoms, isDev, + isWindows, + isMacOS, atoms, createBlock, showContextMenu: (menu: ContextMenuItem[], e: React.MouseEvent) => { diff --git a/frontend/preview/mock/mockwaveenv.test.ts b/frontend/preview/mock/mockwaveenv.test.ts new file mode 100644 index 0000000000..f305493be6 --- /dev/null +++ b/frontend/preview/mock/mockwaveenv.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from "vitest"; +import { PlatformMacOS, PlatformWindows } from "@/util/platformutil"; +import { applyMockEnvOverrides, makeMockWaveEnv } from "./mockwaveenv"; + +describe("makeMockWaveEnv", () => { + it("defaults the platform to macOS", () => { + const env = makeMockWaveEnv(); + + expect(env.platform).toBe(PlatformMacOS); + expect(env.electron.getPlatform()).toBe(PlatformMacOS); + expect(env.isMacOS()).toBe(true); + expect(env.isWindows()).toBe(false); + }); + + it("allows overriding the platform", () => { + const env = makeMockWaveEnv({ platform: PlatformWindows }); + + expect(env.platform).toBe(PlatformWindows); + expect(env.electron.getPlatform()).toBe(PlatformWindows); + expect(env.isMacOS()).toBe(false); + expect(env.isWindows()).toBe(true); + }); + + it("preserves platform overrides when applying mock env overrides", () => { + const env = makeMockWaveEnv(); + const updatedEnv = applyMockEnvOverrides(env, { platform: PlatformWindows }); + + expect(updatedEnv.platform).toBe(PlatformWindows); + expect(updatedEnv.isWindows()).toBe(true); + expect(updatedEnv.isMacOS()).toBe(false); + }); +}); diff --git a/frontend/preview/mock/mockwaveenv.ts b/frontend/preview/mock/mockwaveenv.ts index 9ed61e2b58..2b704dd574 100644 --- a/frontend/preview/mock/mockwaveenv.ts +++ b/frontend/preview/mock/mockwaveenv.ts @@ -4,6 +4,7 @@ import { getSettingsKeyAtom, makeDefaultConnStatus } from "@/app/store/global"; import { RpcApiType } from "@/app/store/wshclientapi"; import { WaveEnv } from "@/app/waveenv/waveenv"; +import { PlatformMacOS, PlatformWindows } from "@/util/platformutil"; import { Atom, atom, PrimitiveAtom } from "jotai"; import { previewElectronApi } from "./preview-electron-api"; @@ -13,6 +14,7 @@ type RpcOverrides = { export type MockEnv = { isDev?: boolean; + platform?: NodeJS.Platform; config?: Partial; rpc?: RpcOverrides; atoms?: Partial; @@ -35,6 +37,7 @@ function mergeRecords(base: Record, overrides: Record): export function mergeMockEnv(base: MockEnv, overrides: MockEnv): MockEnv { return { isDev: overrides.isDev ?? base.isDev, + platform: overrides.platform ?? base.platform, config: mergeRecords(base.config, overrides.config), rpc: mergeRecords(base.rpc as any, overrides.rpc as any) as RpcOverrides, atoms: @@ -134,16 +137,24 @@ export function applyMockEnvOverrides(env: WaveEnv, newOverrides: MockEnv): Mock export function makeMockWaveEnv(mockEnv?: MockEnv): MockWaveEnv { const overrides: MockEnv = mockEnv ?? {}; + const platform = overrides.platform ?? PlatformMacOS; const connStatusAtomCache = new Map>(); const waveObjectAtomCache = new Map>(); const blockMetaKeyAtomCache = new Map>(); const env = { mockEnv: overrides, - electron: overrides.electron ? { ...previewElectronApi, ...overrides.electron } : previewElectronApi, + electron: { + ...previewElectronApi, + getPlatform: () => platform, + ...overrides.electron, + }, rpc: makeMockRpc(overrides.rpc), + platform, configAtoms: makeMockConfigAtoms(overrides.config), atoms: makeMockGlobalAtoms(overrides.atoms), isDev: () => overrides.isDev ?? true, + isWindows: () => platform == PlatformWindows, + isMacOS: () => platform == PlatformMacOS, createBlock: overrides.createBlock ?? ((blockDef: BlockDef, magnified?: boolean, ephemeral?: boolean) => { From 405bb057dc74fb97957dbad4ff69406dfc7edbdf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:34:21 +0000 Subject: [PATCH 3/4] Finish WaveEnv platform wiring Co-authored-by: sawka <2722291+sawka@users.noreply.github.com> --- frontend/preview/mock/mockwaveenv.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/preview/mock/mockwaveenv.ts b/frontend/preview/mock/mockwaveenv.ts index 2b704dd574..a8b4af1ee5 100644 --- a/frontend/preview/mock/mockwaveenv.ts +++ b/frontend/preview/mock/mockwaveenv.ts @@ -153,8 +153,8 @@ export function makeMockWaveEnv(mockEnv?: MockEnv): MockWaveEnv { configAtoms: makeMockConfigAtoms(overrides.config), atoms: makeMockGlobalAtoms(overrides.atoms), isDev: () => overrides.isDev ?? true, - isWindows: () => platform == PlatformWindows, - isMacOS: () => platform == PlatformMacOS, + isWindows: () => platform === PlatformWindows, + isMacOS: () => platform === PlatformMacOS, createBlock: overrides.createBlock ?? ((blockDef: BlockDef, magnified?: boolean, ephemeral?: boolean) => { From c38d815f368aa3b7b6b74abb5643aefae5e11f13 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:41:32 +0000 Subject: [PATCH 4/4] Remove trivial WaveEnv tests Co-authored-by: sawka <2722291+sawka@users.noreply.github.com> --- frontend/app/waveenv/waveenvimpl.test.ts | 43 ----------------------- frontend/preview/mock/mockwaveenv.test.ts | 32 ----------------- 2 files changed, 75 deletions(-) delete mode 100644 frontend/app/waveenv/waveenvimpl.test.ts delete mode 100644 frontend/preview/mock/mockwaveenv.test.ts diff --git a/frontend/app/waveenv/waveenvimpl.test.ts b/frontend/app/waveenv/waveenvimpl.test.ts deleted file mode 100644 index 06991263ea..0000000000 --- a/frontend/app/waveenv/waveenvimpl.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { describe, expect, it, vi } from "vitest"; - -describe("makeWaveEnvImpl", () => { - it("exposes platform helpers from platformutil", async () => { - const showContextMenu = vi.fn(); - const windowApi = { name: "electron-api" } as ElectronApi; - - vi.resetModules(); - vi.stubGlobal("window", { api: windowApi }); - vi.doMock("@/app/store/contextmenu", () => ({ - ContextMenuModel: { - getInstance: () => ({ - showContextMenu, - }), - }, - })); - vi.doMock("@/app/store/global", () => ({ - atoms: { workspace: "workspace-atom" }, - createBlock: vi.fn(), - getBlockMetaKeyAtom: vi.fn(), - getConnStatusAtom: vi.fn(), - getSettingsKeyAtom: vi.fn(), - isDev: vi.fn(() => true), - WOS: { getWaveObjectAtom: vi.fn() }, - })); - vi.doMock("@/app/store/wshclientapi", () => ({ - RpcApi: { name: "rpc-api" }, - })); - vi.doMock("@/util/platformutil", () => ({ - PLATFORM: "win32", - isWindows: vi.fn(() => true), - isMacOS: vi.fn(() => false), - })); - - const { makeWaveEnvImpl } = await import("./waveenvimpl"); - const env = makeWaveEnvImpl(); - - expect(env.electron).toBe(windowApi); - expect(env.platform).toBe("win32"); - expect(env.isWindows()).toBe(true); - expect(env.isMacOS()).toBe(false); - }); -}); diff --git a/frontend/preview/mock/mockwaveenv.test.ts b/frontend/preview/mock/mockwaveenv.test.ts deleted file mode 100644 index f305493be6..0000000000 --- a/frontend/preview/mock/mockwaveenv.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { PlatformMacOS, PlatformWindows } from "@/util/platformutil"; -import { applyMockEnvOverrides, makeMockWaveEnv } from "./mockwaveenv"; - -describe("makeMockWaveEnv", () => { - it("defaults the platform to macOS", () => { - const env = makeMockWaveEnv(); - - expect(env.platform).toBe(PlatformMacOS); - expect(env.electron.getPlatform()).toBe(PlatformMacOS); - expect(env.isMacOS()).toBe(true); - expect(env.isWindows()).toBe(false); - }); - - it("allows overriding the platform", () => { - const env = makeMockWaveEnv({ platform: PlatformWindows }); - - expect(env.platform).toBe(PlatformWindows); - expect(env.electron.getPlatform()).toBe(PlatformWindows); - expect(env.isMacOS()).toBe(false); - expect(env.isWindows()).toBe(true); - }); - - it("preserves platform overrides when applying mock env overrides", () => { - const env = makeMockWaveEnv(); - const updatedEnv = applyMockEnvOverrides(env, { platform: PlatformWindows }); - - expect(updatedEnv.platform).toBe(PlatformWindows); - expect(updatedEnv.isWindows()).toBe(true); - expect(updatedEnv.isMacOS()).toBe(false); - }); -});