authorclover caruso <git@paperclover.net> 2026-10-16 00:08:15-07:00
committerclover caruso <git@paperclover.net> 2026-10-16 16:52:04-07:00
log0b3f74c4692000e2979902e327e147f623276230
tree956948ead2ac80d52939c0032e5ffa80bc9dba8d
parenta4d2ec0fc271b30cf89a4a5153c9b6cf44a986ca
signature Signed by SSH key SHA256:cOKiuRFOeSRxne6EWgHtdQQSlBxjOXm2hOCFnCdLQbQ (~clover)

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

7 files changed, 29 insertions(+), 40 deletions(-)

apps/web/src/components/settings/settingsNavigation.tsx+1-1
......@@ -56,7 +56,7 @@ const SETTINGS_NAV_ITEMS: ReadonlyArray<{
5656 to: SettingsPath;
5757 icon: ComponentType<{ className?: string }>;
5858}> = (Object.keys(SETTINGS_SECTION_LABELS) as SettingsPath[])
59 .filter((to) => to !== "/settings/diagnostics")
59 .filter((to) => to !== "/settings/diagnostics" && to !== "/settings/snap-shot")
6060 .map((to) => ({
6161 to,
6262 label: SETTINGS_SECTION_LABELS[to],
apps/web/src/components/settings/settingsSearch.test.ts+8-19
......@@ -339,25 +339,14 @@ describe("searchSettings", () => {
339339 });
340340 });
341341
342 it("routes conditional window capture settings to the stable toggle row", () => {
343 const targets = [
344 "capture accessibility data",
345 "capture shortcut",
346 "capture sound",
347 "capture flash",
348 "capture animations",
349 ].map((query) => {
350 const match = searchSettings(query)[0];
351 return [match?.id, match?.targetId];
352 });
353
354 expect(targets).toEqual([
355 ["snap-shot-accessibility", "snap-shot-enabled"],
356 ["snap-shot-shortcut", "snap-shot-enabled"],
357 ["snap-shot-sound", "snap-shot-enabled"],
358 ["snap-shot-flash", "snap-shot-enabled"],
359 ["snap-shot-animations", "snap-shot-enabled"],
360 ]);
342 it.each([
343 "capture accessibility data",
344 "capture shortcut",
345 "capture sound",
346 "capture flash",
347 "capture animations",
348 ])("hides disabled SnapShots settings for %s", (query) => {
349 expect(searchSettings(query).some((item) => item.to === "/settings/snap-shot")).toBe(false);
361350 });
362351
363352 it("routes browser recording quality to integrations", () => {
apps/web/src/components/settings/settingsSearch.ts+2
......@@ -1153,6 +1153,7 @@ export function filterAvailableSettingsSearchItems(
11531153 const items: ReadonlyArray<SettingsSearchItem> = SETTINGS_SEARCH_ITEMS;
11541154 return items.filter(
11551155 (item) =>
1156 item.to !== "/settings/snap-shot" &&
11561157 (!item.cloudOnly || availability.hasCloudPublicConfig) &&
11571158 (!item.environmentOnly || availability.hasEnvironment) &&
11581159 (!item.providerSettingsOnly || availability.hasProviderSettingsEnvironment) &&
......@@ -1176,6 +1177,7 @@ export function searchSettings(
11761177
11771178 return items
11781179 .flatMap((item, index) => {
1180 if (item.to === "/settings/snap-shot") return [];
11791181 if (!isElectron && item.desktopOnly === true) return [];
11801182 if (item.releaseChannelOnly && !isElectron && HOSTED_APP_CHANNEL === null) return [];
11811183 if (item.macOnly && !isMacPlatform(platform)) return [];
apps/web/src/routes/__root.tsx-11
......@@ -5,7 +5,6 @@ import { scopedProjectKey, scopeProjectRef } from "@t3tools/client-runtime/envir
55import {
66 Outlet,
77 Link,
8 redirect,
98 createRootRoute,
109 type ErrorComponentProps,
1110 useLocation,
......@@ -85,9 +84,7 @@ import {
8584 type KeybindingsUpdateToastController,
8685} from "../components/KeybindingsUpdateToast.logic";
8786
88import { getDesktopSnapShotBridge } from "../lib/desktopSnapShot";
8987import { installDesktopPasteAsText } from "../lib/desktopPasteAsText";
90import { shouldResumeSnapShotSetupOnStartup } from "../lib/snapShotSetupResume";
9188
9289export const Route = createRootRoute({
9390 beforeLoad: async ({ location }) => {
......@@ -108,14 +105,6 @@ export const Route = createRootRoute({
108105 }
109106
110107 const authGateState = await resolveInitialServerAuthGateState();
111 if (
112 authGateState.status === "authenticated" &&
113 getDesktopSnapShotBridge() &&
114 shouldResumeSnapShotSetupOnStartup() &&
115 location.pathname !== "/settings/snap-shot"
116 ) {
117 throw redirect({ to: "/settings/snap-shot", replace: true });
118 }
119108 return {
120109 authGateState,
121110 };
apps/web/src/routes/settings.snap-shot.tsx+4-8
......@@ -1,11 +1,7 @@
1import { createFileRoute } from "@tanstack/react-router";
2
3import { SnapShotSettings } from "../components/settings/SnapShotSettings";
4
5function SettingsSnapShotRoute() {
6 return <SnapShotSettings />;
7}
1import { createFileRoute, redirect } from "@tanstack/react-router";
82
93export const Route = createFileRoute("/settings/snap-shot")({
10 component: SettingsSnapShotRoute,
4 beforeLoad: () => {
5 throw redirect({ to: "/settings/general", replace: true });
6 },
117});
packages/contracts/src/settings.test.ts+7
......@@ -8,6 +8,7 @@ import {
88 ClientSettingsPatch,
99 ClaudeSettings,
1010 DEFAULT_SERVER_SETTINGS,
11 DEFAULT_CLIENT_SETTINGS,
1112 requiredScopesForProjectMutation,
1213 resolveProjectProviderInstanceEnabled,
1314 resolveProviderInstanceEnabled,
......@@ -473,6 +474,12 @@ describe("ClientSettings window capture", () => {
473474 });
474475 });
475476
477 it("keeps SnapShots disabled when older settings enable them or a caller tries to persist them", () => {
478 expect(decodeClientSettings({ snapShotEnabled: true }).snapShotEnabled).toBe(false);
479 const saved = encodeClientSettings({ ...DEFAULT_CLIENT_SETTINGS, snapShotEnabled: true });
480 expect(saved.snapShotEnabled).toBe(false);
481 });
482
476483 it("rejects unknown capture sounds", () => {
477484 expect(() => decodeClientSettingsPatch({ snapShotSound: "doorbell" })).toThrow();
478485 });
packages/contracts/src/settings.ts+7-1
......@@ -491,7 +491,13 @@ export const ClientSettingsSchema = Schema.Struct({
491491 timestampFormat: TimestampFormat.pipe(
492492 Schema.withDecodingDefault(Effect.succeed(DEFAULT_TIMESTAMP_FORMAT)),
493493 ),
494 snapShotEnabled: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))),
494 snapShotEnabled: Schema.Boolean.pipe(
495 Schema.decodeTo(
496 Schema.Boolean,
497 SchemaTransformation.transform({ decode: () => false, encode: () => false }),
498 ),
499 Schema.withDecodingDefault(Effect.succeed(false)),
500 ),
495501 snapShotIncludeAccessibility: Schema.Boolean.pipe(
496502 Schema.withDecodingDefault(Effect.succeed(true)),
497503 ),