From 0b3f74c4692000e2979902e327e147f623276230 Mon Sep 17 00:00:00 2001 From: clover caruso Date: Fri, 16 Oct 2026 00:08:15 -0700 Subject: [PATCH] feat: disable SnapShots in the fork Clover does not want desktop SnapShots in this build. Hide capture settings from navigation and search, redirect the old settings URL, and remove the startup setup-resume redirect. Decode and persist capture enablement as false so previously enabled settings and native IPC updates cannot turn capture back on. Assisted-by: gpt-6.1-sol --- .../settings/settingsNavigation.tsx | 2 +- .../settings/settingsSearch.test.ts | 27 ++++++------------- .../src/components/settings/settingsSearch.ts | 2 ++ apps/web/src/routes/__root.tsx | 11 -------- apps/web/src/routes/settings.snap-shot.tsx | 12 +++------ packages/contracts/src/settings.test.ts | 7 +++++ packages/contracts/src/settings.ts | 8 +++++- 7 files changed, 29 insertions(+), 40 deletions(-) diff --git a/apps/web/src/components/settings/settingsNavigation.tsx b/apps/web/src/components/settings/settingsNavigation.tsx index 3cf107458d08e03a06d5377977a8d9aaf952b934..81bd82186944a0ae100baaa810129676e572779a 100644 --- a/apps/web/src/components/settings/settingsNavigation.tsx +++ b/apps/web/src/components/settings/settingsNavigation.tsx @@ -56,7 +56,7 @@ const SETTINGS_NAV_ITEMS: ReadonlyArray<{ to: SettingsPath; icon: ComponentType<{ className?: string }>; }> = (Object.keys(SETTINGS_SECTION_LABELS) as SettingsPath[]) - .filter((to) => to !== "/settings/diagnostics") + .filter((to) => to !== "/settings/diagnostics" && to !== "/settings/snap-shot") .map((to) => ({ to, label: SETTINGS_SECTION_LABELS[to], diff --git a/apps/web/src/components/settings/settingsSearch.test.ts b/apps/web/src/components/settings/settingsSearch.test.ts index b3d7b0c29a60206d2ae5da55f93d2da157c7a03a..d72ba871469856cc1e30905a47bcff8d991a98c3 100644 --- a/apps/web/src/components/settings/settingsSearch.test.ts +++ b/apps/web/src/components/settings/settingsSearch.test.ts @@ -339,25 +339,14 @@ describe("searchSettings", () => { }); }); - it("routes conditional window capture settings to the stable toggle row", () => { - const targets = [ - "capture accessibility data", - "capture shortcut", - "capture sound", - "capture flash", - "capture animations", - ].map((query) => { - const match = searchSettings(query)[0]; - return [match?.id, match?.targetId]; - }); - - expect(targets).toEqual([ - ["snap-shot-accessibility", "snap-shot-enabled"], - ["snap-shot-shortcut", "snap-shot-enabled"], - ["snap-shot-sound", "snap-shot-enabled"], - ["snap-shot-flash", "snap-shot-enabled"], - ["snap-shot-animations", "snap-shot-enabled"], - ]); + it.each([ + "capture accessibility data", + "capture shortcut", + "capture sound", + "capture flash", + "capture animations", + ])("hides disabled SnapShots settings for %s", (query) => { + expect(searchSettings(query).some((item) => item.to === "/settings/snap-shot")).toBe(false); }); it("routes browser recording quality to integrations", () => { diff --git a/apps/web/src/components/settings/settingsSearch.ts b/apps/web/src/components/settings/settingsSearch.ts index 723b39f6a0d9319d0c5366d789148ed38c83aa5c..a63ef8209cf3d742e92afbbd4bbbeaccb9a0e3a3 100644 --- a/apps/web/src/components/settings/settingsSearch.ts +++ b/apps/web/src/components/settings/settingsSearch.ts @@ -1153,6 +1153,7 @@ export function filterAvailableSettingsSearchItems( const items: ReadonlyArray = SETTINGS_SEARCH_ITEMS; return items.filter( (item) => + item.to !== "/settings/snap-shot" && (!item.cloudOnly || availability.hasCloudPublicConfig) && (!item.environmentOnly || availability.hasEnvironment) && (!item.providerSettingsOnly || availability.hasProviderSettingsEnvironment) && @@ -1176,6 +1177,7 @@ export function searchSettings( return items .flatMap((item, index) => { + if (item.to === "/settings/snap-shot") return []; if (!isElectron && item.desktopOnly === true) return []; if (item.releaseChannelOnly && !isElectron && HOSTED_APP_CHANNEL === null) return []; if (item.macOnly && !isMacPlatform(platform)) return []; diff --git a/apps/web/src/routes/__root.tsx b/apps/web/src/routes/__root.tsx index 8e43622738d95e8a041d9ecda79ae4b79250c82f..f2301f4d7604fb6e0f32fd7f4c1e2a10a136cb31 100644 --- a/apps/web/src/routes/__root.tsx +++ b/apps/web/src/routes/__root.tsx @@ -5,7 +5,6 @@ import { scopedProjectKey, scopeProjectRef } from "@t3tools/client-runtime/envir import { Outlet, Link, - redirect, createRootRoute, type ErrorComponentProps, useLocation, @@ -85,9 +84,7 @@ import { type KeybindingsUpdateToastController, } from "../components/KeybindingsUpdateToast.logic"; -import { getDesktopSnapShotBridge } from "../lib/desktopSnapShot"; import { installDesktopPasteAsText } from "../lib/desktopPasteAsText"; -import { shouldResumeSnapShotSetupOnStartup } from "../lib/snapShotSetupResume"; export const Route = createRootRoute({ beforeLoad: async ({ location }) => { @@ -108,14 +105,6 @@ export const Route = createRootRoute({ } const authGateState = await resolveInitialServerAuthGateState(); - if ( - authGateState.status === "authenticated" && - getDesktopSnapShotBridge() && - shouldResumeSnapShotSetupOnStartup() && - location.pathname !== "/settings/snap-shot" - ) { - throw redirect({ to: "/settings/snap-shot", replace: true }); - } return { authGateState, }; diff --git a/apps/web/src/routes/settings.snap-shot.tsx b/apps/web/src/routes/settings.snap-shot.tsx index 0b7a96dc42b6fddf1edefce7d00230e39e4f6c40..6cc4da465632f8a44f21280f4101991be4b72bb3 100644 --- a/apps/web/src/routes/settings.snap-shot.tsx +++ b/apps/web/src/routes/settings.snap-shot.tsx @@ -1,11 +1,7 @@ -import { createFileRoute } from "@tanstack/react-router"; - -import { SnapShotSettings } from "../components/settings/SnapShotSettings"; - -function SettingsSnapShotRoute() { - return ; -} +import { createFileRoute, redirect } from "@tanstack/react-router"; export const Route = createFileRoute("/settings/snap-shot")({ - component: SettingsSnapShotRoute, + beforeLoad: () => { + throw redirect({ to: "/settings/general", replace: true }); + }, }); diff --git a/packages/contracts/src/settings.test.ts b/packages/contracts/src/settings.test.ts index c289b4a2592547298c6736b982a194d431875ac5..c343f73fec816467445dd9e8062f1985cc31607c 100644 --- a/packages/contracts/src/settings.test.ts +++ b/packages/contracts/src/settings.test.ts @@ -8,6 +8,7 @@ import { ClientSettingsPatch, ClaudeSettings, DEFAULT_SERVER_SETTINGS, + DEFAULT_CLIENT_SETTINGS, requiredScopesForProjectMutation, resolveProjectProviderInstanceEnabled, resolveProviderInstanceEnabled, @@ -473,6 +474,12 @@ describe("ClientSettings window capture", () => { }); }); + it("keeps SnapShots disabled when older settings enable them or a caller tries to persist them", () => { + expect(decodeClientSettings({ snapShotEnabled: true }).snapShotEnabled).toBe(false); + const saved = encodeClientSettings({ ...DEFAULT_CLIENT_SETTINGS, snapShotEnabled: true }); + expect(saved.snapShotEnabled).toBe(false); + }); + it("rejects unknown capture sounds", () => { expect(() => decodeClientSettingsPatch({ snapShotSound: "doorbell" })).toThrow(); }); diff --git a/packages/contracts/src/settings.ts b/packages/contracts/src/settings.ts index 52ebb8947c7762c7a4de47520d6db445b1dd2502..237160cf07115df154a6b4db719c8909b364d4f9 100644 --- a/packages/contracts/src/settings.ts +++ b/packages/contracts/src/settings.ts @@ -491,7 +491,13 @@ export const ClientSettingsSchema = Schema.Struct({ timestampFormat: TimestampFormat.pipe( Schema.withDecodingDefault(Effect.succeed(DEFAULT_TIMESTAMP_FORMAT)), ), - snapShotEnabled: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), + snapShotEnabled: Schema.Boolean.pipe( + Schema.decodeTo( + Schema.Boolean, + SchemaTransformation.transform({ decode: () => false, encode: () => false }), + ), + Schema.withDecodingDefault(Effect.succeed(false)), + ), snapShotIncludeAccessibility: Schema.Boolean.pipe( Schema.withDecodingDefault(Effect.succeed(true)), ), -- 2.54.0