From 17e2cdfc853220c755336e0348bd39d734f33d8f Mon Sep 17 00:00:00 2001 From: Stefan de Vogelaere Date: Sat, 17 Jan 2026 15:33:51 +0100 Subject: [PATCH 1/2] fix: sandbox warning persistence and add env var option Fix race condition where sandbox warning appeared on every refresh even after checking "Do not show again". The issue was that the sandbox check effect ran before settings were hydrated from the server, so skipSandboxWarning was always false (the default). Changes: - Add settingsLoaded to sandbox check dependencies to ensure the user's preference is loaded before checking - Add AUTOMAKER_SKIP_SANDBOX_WARNING env var option to skip the warning entirely (useful for dev/CI environments) --- .../src/routes/health/routes/environment.ts | 2 ++ apps/ui/src/lib/http-api-client.ts | 6 +++++- apps/ui/src/routes/__root.tsx | 20 +++++++++++++------ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/server/src/routes/health/routes/environment.ts b/apps/server/src/routes/health/routes/environment.ts index ee5f7d53..8e5a89c9 100644 --- a/apps/server/src/routes/health/routes/environment.ts +++ b/apps/server/src/routes/health/routes/environment.ts @@ -9,12 +9,14 @@ import type { Request, Response } from 'express'; export interface EnvironmentResponse { isContainerized: boolean; + skipSandboxWarning?: boolean; } export function createEnvironmentHandler() { return (_req: Request, res: Response): void => { res.json({ isContainerized: process.env.IS_CONTAINERIZED === 'true', + skipSandboxWarning: process.env.AUTOMAKER_SKIP_SANDBOX_WARNING === 'true', } satisfies EnvironmentResponse); }; } diff --git a/apps/ui/src/lib/http-api-client.ts b/apps/ui/src/lib/http-api-client.ts index d7ac5280..cd0e6739 100644 --- a/apps/ui/src/lib/http-api-client.ts +++ b/apps/ui/src/lib/http-api-client.ts @@ -483,6 +483,7 @@ export const verifySession = async (): Promise => { */ export const checkSandboxEnvironment = async (): Promise<{ isContainerized: boolean; + skipSandboxWarning?: boolean; error?: string; }> => { try { @@ -498,7 +499,10 @@ export const checkSandboxEnvironment = async (): Promise<{ } const data = await response.json(); - return { isContainerized: data.isContainerized ?? false }; + return { + isContainerized: data.isContainerized ?? false, + skipSandboxWarning: data.skipSandboxWarning ?? false, + }; } catch (error) { logger.error('Sandbox environment check failed:', error); return { isContainerized: false, error: 'Network error' }; diff --git a/apps/ui/src/routes/__root.tsx b/apps/ui/src/routes/__root.tsx index f3a662e8..9c118967 100644 --- a/apps/ui/src/routes/__root.tsx +++ b/apps/ui/src/routes/__root.tsx @@ -252,15 +252,16 @@ function RootLayoutContent() { setIsMounted(true); }, []); - // Check sandbox environment only after user is authenticated and setup is complete + // Check sandbox environment only after user is authenticated, setup is complete, and settings are loaded useEffect(() => { // Skip if already decided if (sandboxStatus !== 'pending') { return; } - // Don't check sandbox until user is authenticated and has completed setup - if (!authChecked || !isAuthenticated || !setupComplete) { + // Don't check sandbox until user is authenticated, has completed setup, and settings are loaded + // CRITICAL: settingsLoaded must be true to ensure skipSandboxWarning has been hydrated from server + if (!authChecked || !isAuthenticated || !setupComplete || !settingsLoaded) { return; } @@ -271,8 +272,8 @@ function RootLayoutContent() { if (result.isContainerized) { // Running in a container, no warning needed setSandboxStatus('containerized'); - } else if (skipSandboxWarning) { - // User opted to skip the warning, auto-confirm + } else if (result.skipSandboxWarning || skipSandboxWarning) { + // Skip if env var is set OR if user preference is set setSandboxStatus('confirmed'); } else { // Not containerized, show warning dialog @@ -290,7 +291,14 @@ function RootLayoutContent() { }; checkSandbox(); - }, [sandboxStatus, skipSandboxWarning, authChecked, isAuthenticated, setupComplete]); + }, [ + sandboxStatus, + skipSandboxWarning, + authChecked, + isAuthenticated, + setupComplete, + settingsLoaded, + ]); // Handle sandbox risk confirmation const handleSandboxConfirm = useCallback( From e69a2ad722322a3001c91b0e4b0a714c0008302d Mon Sep 17 00:00:00 2001 From: Stefan de Vogelaere Date: Sat, 17 Jan 2026 18:33:08 +0100 Subject: [PATCH 2/2] docs: add AUTOMAKER_SKIP_SANDBOX_WARNING env var documentation Document the new environment variable in README.md and .env.example --- README.md | 1 + apps/server/.env.example | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/README.md b/README.md index 60dba6d4..3f9889fc 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,7 @@ npm run lint - `VITE_SKIP_ELECTRON` - Skip Electron in dev mode - `OPEN_DEVTOOLS` - Auto-open DevTools in Electron +- `AUTOMAKER_SKIP_SANDBOX_WARNING` - Skip sandbox warning dialog (useful for dev/CI) ### Authentication Setup diff --git a/apps/server/.env.example b/apps/server/.env.example index 6ac27145..a73e3443 100644 --- a/apps/server/.env.example +++ b/apps/server/.env.example @@ -68,6 +68,14 @@ TERMINAL_PASSWORD= ENABLE_REQUEST_LOGGING=false +# ============================================ +# OPTIONAL - UI Behavior +# ============================================ + +# Skip the sandbox warning dialog on startup (default: false) +# Set to "true" to disable the warning entirely (useful for dev/CI environments) +AUTOMAKER_SKIP_SANDBOX_WARNING=false + # ============================================ # OPTIONAL - Debugging # ============================================