From 3e396d1d53606dabecada2f28e8e366945c2c3ca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 23:10:30 +0000 Subject: [PATCH 1/3] Initial plan From c787b5c82d35cfd6000b8404ccf467d919950f4f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 23:15:01 +0000 Subject: [PATCH 2/3] feat: support workspace-scoped widgets config Co-authored-by: sawka <2722291+sawka@users.noreply.github.com> --- frontend/app/workspace/widgetfilter.test.ts | 16 ++++++++++++++++ frontend/app/workspace/widgetfilter.ts | 9 +++++++++ frontend/app/workspace/widgets.tsx | 13 ++++++++++--- frontend/types/gotypes.d.ts | 1 + pkg/wconfig/settingsconfig.go | 1 + 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 frontend/app/workspace/widgetfilter.test.ts create mode 100644 frontend/app/workspace/widgetfilter.ts diff --git a/frontend/app/workspace/widgetfilter.test.ts b/frontend/app/workspace/widgetfilter.test.ts new file mode 100644 index 0000000000..535c62ac9c --- /dev/null +++ b/frontend/app/workspace/widgetfilter.test.ts @@ -0,0 +1,16 @@ +// Copyright 2025, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +import { assert, test } from "vitest"; +import { shouldIncludeWidgetForWorkspace } from "./widgetfilter"; + +test("shouldIncludeWidgetForWorkspace includes widgets with missing or empty workspaces", () => { + assert(shouldIncludeWidgetForWorkspace({ blockdef: { meta: {} } }, "ws-1")); + assert(shouldIncludeWidgetForWorkspace({ blockdef: { meta: {} }, workspaces: [] }, "ws-1")); +}); + +test("shouldIncludeWidgetForWorkspace only includes configured workspace IDs", () => { + assert(shouldIncludeWidgetForWorkspace({ blockdef: { meta: {} }, workspaces: ["ws-1", "ws-2"] }, "ws-1")); + assert(!shouldIncludeWidgetForWorkspace({ blockdef: { meta: {} }, workspaces: ["ws-1", "ws-2"] }, "ws-3")); + assert(!shouldIncludeWidgetForWorkspace({ blockdef: { meta: {} }, workspaces: ["ws-1"] }, null)); +}); diff --git a/frontend/app/workspace/widgetfilter.ts b/frontend/app/workspace/widgetfilter.ts new file mode 100644 index 0000000000..c8eb5b82c7 --- /dev/null +++ b/frontend/app/workspace/widgetfilter.ts @@ -0,0 +1,9 @@ +// Copyright 2025, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +function shouldIncludeWidgetForWorkspace(widget: WidgetConfigType, workspaceId?: string): boolean { + const workspaces = widget.workspaces; + return !Array.isArray(workspaces) || workspaces.length === 0 || (workspaceId != null && workspaces.includes(workspaceId)); +} + +export { shouldIncludeWidgetForWorkspace }; diff --git a/frontend/app/workspace/widgets.tsx b/frontend/app/workspace/widgets.tsx index 39d3237766..91717a746f 100644 --- a/frontend/app/workspace/widgets.tsx +++ b/frontend/app/workspace/widgets.tsx @@ -5,6 +5,7 @@ import { Tooltip } from "@/app/element/tooltip"; import { ContextMenuModel } from "@/app/store/contextmenu"; import { RpcApi } from "@/app/store/wshclientapi"; import { TabRpcClient } from "@/app/store/wshrpcutil"; +import { shouldIncludeWidgetForWorkspace } from "@/app/workspace/widgetfilter"; import { atoms, createBlock, isDev } from "@/store/global"; import { fireAndForget, isBlank, makeIconClass } from "@/util/util"; import { @@ -314,6 +315,7 @@ SettingsFloatingWindow.displayName = "SettingsFloatingWindow"; const Widgets = memo(() => { const fullConfig = useAtomValue(atoms.fullConfigAtom); + const workspace = useAtomValue(atoms.workspace); const hasCustomAIPresets = useAtomValue(atoms.hasCustomAIPresetsAtom); const [mode, setMode] = useState<"normal" | "compact" | "supercompact">("normal"); const containerRef = useRef(null); @@ -321,9 +323,14 @@ const Widgets = memo(() => { const featureWaveAppBuilder = fullConfig?.settings?.["feature:waveappbuilder"] ?? false; const widgetsMap = fullConfig?.widgets ?? {}; - const filteredWidgets = hasCustomAIPresets - ? widgetsMap - : Object.fromEntries(Object.entries(widgetsMap).filter(([key]) => key !== "defwidget@ai")); + const filteredWidgets = Object.fromEntries( + Object.entries(widgetsMap).filter(([key, widget]) => { + if (!hasCustomAIPresets && key === "defwidget@ai") { + return false; + } + return shouldIncludeWidgetForWorkspace(widget, workspace?.oid); + }) + ); const widgets = sortByDisplayOrder(filteredWidgets); const [isAppsOpen, setIsAppsOpen] = useState(false); diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 6d60ed8e32..3b8f53f6ef 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -2075,6 +2075,7 @@ declare global { color?: string; label?: string; description?: string; + workspaces?: string[]; magnified?: boolean; blockdef: BlockDef; }; diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go index 78f8ccb1db..5965ee9d8b 100644 --- a/pkg/wconfig/settingsconfig.go +++ b/pkg/wconfig/settingsconfig.go @@ -829,6 +829,7 @@ type WidgetConfigType struct { Color string `json:"color,omitempty"` Label string `json:"label,omitempty"` Description string `json:"description,omitempty"` + Workspaces []string `json:"workspaces,omitempty"` Magnified bool `json:"magnified,omitempty"` BlockDef waveobj.BlockDef `json:"blockdef"` } From 0b9fc1b1d76d6d38c2223aaa93bb773005aae81b Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 19 Feb 2026 15:27:18 -0800 Subject: [PATCH 3/3] run task generate --- frontend/types/gotypes.d.ts | 2 ++ schema/widgets.json | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 3b8f53f6ef..4c7660effb 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -1455,6 +1455,8 @@ declare global { "conn:conntype"?: string; "conn:wsherrorcode"?: string; "conn:errorcode"?: string; + "conn:suberrorcode"?: string; + "conn:contexterror"?: boolean; "onboarding:feature"?: "waveai" | "durable" | "magnify" | "wsh"; "onboarding:version"?: string; "onboarding:githubstar"?: "already" | "star" | "later"; diff --git a/schema/widgets.json b/schema/widgets.json index 54f1aab0c7..1db6e48c6f 100644 --- a/schema/widgets.json +++ b/schema/widgets.json @@ -51,6 +51,12 @@ "description": { "type": "string" }, + "workspaces": { + "items": { + "type": "string" + }, + "type": "array" + }, "magnified": { "type": "boolean" },