From bb2de72f6f28b60d87436d5855d853a53bfe143b Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 26 May 2026 00:29:17 -0700 Subject: [PATCH] [eric] windows 1.1.59: production webpack and framer-motion shim --- electron/package.json | 2 +- frontend/package.json | 2 +- frontend/src/app/Main.tsx | 57 +++---------------- .../Onboarding/OnboardingDockedTab.tsx | 2 +- .../components/Onboarding/OnboardingPanel.tsx | 2 +- .../Onboarding/OnboardingRoadmapModal.tsx | 2 +- .../components/Onboarding/OnboardingRoot.tsx | 4 -- .../app/components/Onboarding/_motionWin.tsx | 48 ++++++++++++++++ .../Onboarding/ac/ACMultiChoice.tsx | 2 +- .../app/components/Onboarding/ac/ACPopup.tsx | 2 +- .../Onboarding/ac/AgenticCursor.tsx | 2 +- .../app/components/feedback/ErrorSlime.tsx | 2 - .../src/app/pages/AgentChat/AgentChat.tsx | 5 -- .../src/app/pages/AgentChat/ChatInput.tsx | 2 - .../model-picker/ModelPickerMenu.tsx | 6 -- .../ChatInput/toolbar/ChatInputToolbar.tsx | 6 -- .../ChatInput/toolbar/ContextRing.tsx | 2 - .../ChatInput/toolbar/ModeControl.tsx | 6 -- .../toolbar/ThinkingLevelControl.tsx | 6 -- .../ChatInput/toolbar/ToolbarActions.tsx | 6 -- .../ChatInput/view/AttachmentChips.tsx | 2 - .../ChatInput/view/ChatInputOverlays.tsx | 2 - .../ChatInput/view/ChatInputView.tsx | 2 - .../ChatInput/view/EditorSurface.tsx | 2 - .../ChatInput/view/SendBlockBanner.tsx | 2 - .../AgentChat/bubbles/CompactionMarker.tsx | 2 - .../pages/AgentChat/bubbles/MessageBubble.tsx | 2 - .../AgentChat/bubbles/StreamingBubble.tsx | 2 - .../app/pages/AgentChat/shell/ApprovalBar.tsx | 2 - .../pages/AgentChat/shell/ContextDrawer.tsx | 2 - .../AgentChat/shell/MessageActionBar.tsx | 2 - .../AgentChat/tool-bubbles/ToolCallBubble.tsx | 2 - .../tool-bubbles/ToolGroupBubble.tsx | 2 - .../app/pages/Dashboard/cards/BrowserCard.tsx | 27 --------- .../src/app/pages/Workflows/WorkflowCard.tsx | 2 - frontend/src/shared/state/agentsSlice.ts | 12 ---- frontend/src/shared/state/settingsSlice.ts | 2 +- frontend/src/shared/ws/WebSocketManager.ts | 2 - 38 files changed, 66 insertions(+), 171 deletions(-) create mode 100644 frontend/src/app/components/Onboarding/_motionWin.tsx diff --git a/electron/package.json b/electron/package.json index 2295bf45..f035514a 100644 --- a/electron/package.json +++ b/electron/package.json @@ -1,6 +1,6 @@ { "name": "openswarm", - "version": "1.1.58", + "version": "1.1.59", "description": "OpenSwarm — AI Agent Orchestrator", "author": "openswarm-ai", "main": "main.js", diff --git a/frontend/package.json b/frontend/package.json index cdb64bd9..6fdc10a3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "Open Swarm — Agent Orchestrator frontend built with React", "scripts": { - "build": "webpack --mode=development", + "build": "webpack --mode=production", "build:watch": "webpack --mode=development --watch", "dev": "webpack serve --mode=development", "clean": "rm -rf dist" diff --git a/frontend/src/app/Main.tsx b/frontend/src/app/Main.tsx index ffbd040b..1669c52e 100644 --- a/frontend/src/app/Main.tsx +++ b/frontend/src/app/Main.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useEffect, useState, useRef, Suspense, lazy } from 'react'; +import React, { useMemo, useEffect, useState, useRef, Suspense } from 'react'; import { Provider } from 'react-redux'; import { HashRouter, Routes, Route } from 'react-router-dom'; import { ThemeProvider as MuiThemeProvider, createTheme, CssBaseline } from '@mui/material'; @@ -21,58 +21,19 @@ import AppShell from './components/Layout/AppShell'; import DashboardSelection from './pages/DashboardSelection/DashboardSelection'; import ErrorBoundary from './components/feedback/ErrorBoundary'; import { setPanelMode, disableOnboardingAfterCrash } from '@/shared/state/onboardingProgressSlice'; -// Wrap every lazy() so each chunk load (request, success, failure) emits a diag line. Chunk-split race against React commit is one of the candidate causes of the packaged-only segfault, so this surfaces if a chunk failed to load in the moment leading up to a crash. -function diagLazy>(name: string, loader: () => Promise<{ default: T } | T>): React.LazyExoticComponent { - return lazy(() => { - // eslint-disable-next-line no-console - console.log('[diag][lazy:requested]', name); - return Promise.resolve() - .then(loader) - .then((mod: any) => { - // eslint-disable-next-line no-console - console.log('[diag][lazy:loaded]', name); - return mod && 'default' in mod ? mod : { default: mod }; - }) - .catch((err) => { - // eslint-disable-next-line no-console - console.error('[diag][lazy:failed]', name, err && err.message, err && err.stack); - throw err; - }); - }); -} -const Skills = diagLazy('Skills', () => import('./pages/Skills/Skills')); -const Tools = diagLazy('Tools', () => import('./pages/Tools/Tools')); -const Modes = diagLazy('Modes', () => import('./pages/Modes/Modes')); -const Views = diagLazy('Views', () => import('./pages/Views/Views')); -const Customization = diagLazy('Customization', () => import('./pages/Customization/Customization')); -const Analytics = diagLazy('Analytics', () => import('./pages/Analytics/Analytics')); -const OnboardingRoot = diagLazy('OnboardingRoot', () => +const Skills = React.lazy(() => import('./pages/Skills/Skills')); +const Tools = React.lazy(() => import('./pages/Tools/Tools')); +const Modes = React.lazy(() => import('./pages/Modes/Modes')); +const Views = React.lazy(() => import('./pages/Views/Views')); +const Customization = React.lazy(() => import('./pages/Customization/Customization')); +const Analytics = React.lazy(() => import('./pages/Analytics/Analytics')); +const OnboardingRoot = React.lazy(() => import('./components/Onboarding').then((m) => ({ default: m.OnboardingRoot })), ); -const SignInGate = diagLazy('SignInGate', () => import('./components/overlays/SignInGate')); +const SignInGate = React.lazy(() => import('./components/overlays/SignInGate')); if (typeof window !== 'undefined') { - // Boot-time env snapshot targets candidates #2 (React prod mode) and #3 (tree-shaking removed side-effectful import): we log NODE_ENV, React version, presence of Emotion's cache stylesheet, and any pre-existing emotion/MUI globals so a post-crash trace shows whether the runtime env matched what the bundle expected. - try { - // eslint-disable-next-line no-console - console.log('[diag][env] NODE_ENV=', (typeof process !== 'undefined' && process.env && process.env.NODE_ENV) || 'undefined', - 'React=', (React as any).version, - 'origin=', window.location.origin, - 'href=', window.location.href); - setTimeout(() => { - try { - const emotionStyles = document.querySelectorAll('style[data-emotion]'); - const muiStyles = document.querySelectorAll('style[data-styled],style[data-mui]'); - // eslint-disable-next-line no-console - console.log('[diag][env] emotion_styles=', emotionStyles.length, 'mui_styles=', muiStyles.length, 'all_styles=', document.styleSheets.length); - } catch (err) { - // eslint-disable-next-line no-console - console.error('[diag][env] style probe failed:', err && (err as Error).message); - } - }, 100); - } catch { /* never let the diag block crash */ } - // Diagnostic global error capture. The packaged bundle has no source maps, so without these handlers the only thing that reaches main-process stderr is "Uncaught TypeError: ... (bundle.js:2)" with zero stack context. Forward error.stack and Redux action.type when available so we can pinpoint the offender across the chat-spawn / workflow rendering paths even in minified prod. window.addEventListener('error', (e) => { try { diff --git a/frontend/src/app/components/Onboarding/OnboardingDockedTab.tsx b/frontend/src/app/components/Onboarding/OnboardingDockedTab.tsx index cba96289..9c39e8ec 100644 --- a/frontend/src/app/components/Onboarding/OnboardingDockedTab.tsx +++ b/frontend/src/app/components/Onboarding/OnboardingDockedTab.tsx @@ -1,7 +1,7 @@ // Docked onboarding home: a small, quiet handle on the right edge that reopens the tour. import React, { useState } from 'react'; -import { motion, AnimatePresence } from 'framer-motion'; +import { motion, AnimatePresence } from './_motionWin'; import { Box, IconButton, Typography, CircularProgress } from '@mui/material'; import CloseIcon from '@mui/icons-material/Close'; import { useClaudeTokens } from '@/shared/styles/ThemeContext'; diff --git a/frontend/src/app/components/Onboarding/OnboardingPanel.tsx b/frontend/src/app/components/Onboarding/OnboardingPanel.tsx index 4c4daff3..958bdaf5 100644 --- a/frontend/src/app/components/Onboarding/OnboardingPanel.tsx +++ b/frontend/src/app/components/Onboarding/OnboardingPanel.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; -import { motion, AnimatePresence } from 'framer-motion'; +import { motion, AnimatePresence } from './_motionWin'; import { Box, Typography, IconButton, Button, ButtonBase } from '@mui/material'; import RemoveIcon from '@mui/icons-material/Remove'; import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; diff --git a/frontend/src/app/components/Onboarding/OnboardingRoadmapModal.tsx b/frontend/src/app/components/Onboarding/OnboardingRoadmapModal.tsx index 0c13ae36..372fbd22 100644 --- a/frontend/src/app/components/Onboarding/OnboardingRoadmapModal.tsx +++ b/frontend/src/app/components/Onboarding/OnboardingRoadmapModal.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Modal, Box, Typography, IconButton, Button } from '@mui/material'; -import { motion, AnimatePresence } from 'framer-motion'; +import { motion, AnimatePresence } from './_motionWin'; import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import LockIcon from '@mui/icons-material/Lock'; diff --git a/frontend/src/app/components/Onboarding/OnboardingRoot.tsx b/frontend/src/app/components/Onboarding/OnboardingRoot.tsx index 916cf1c8..c528757e 100644 --- a/frontend/src/app/components/Onboarding/OnboardingRoot.tsx +++ b/frontend/src/app/components/Onboarding/OnboardingRoot.tsx @@ -24,10 +24,6 @@ import { report } from './telemetry'; const PERSIST_DEBOUNCE_MS = 200; const OnboardingRoot: React.FC = () => { - // Windows nuclear ablation v1.1.58: the AgenticCursor motion.div gate in 1.1.57 was not sufficient — OnboardingPanel / OnboardingDirector / popups have additional Framer Motion + portal subtrees that segfault on commit. Return null on Windows so the entire onboarding UI is suppressed; user can still use the app normally without the guided tour. Mac unchanged. - if (typeof navigator !== 'undefined' && navigator.userAgent.includes('Windows')) { - return null; - } const acRef = useRef(null); const dispatch = useAppDispatch(); const store = useStore() as Store; diff --git a/frontend/src/app/components/Onboarding/_motionWin.tsx b/frontend/src/app/components/Onboarding/_motionWin.tsx new file mode 100644 index 00000000..e99c7ee7 --- /dev/null +++ b/frontend/src/app/components/Onboarding/_motionWin.tsx @@ -0,0 +1,48 @@ +// Windows-aware shim for framer-motion. On Mac, re-exports the real library; on Windows, motion.* becomes a plain HTML element (no animation, no Framer runtime, no segfault). AnimatePresence passes children through. Onboarding files import from here so a single Mac/Windows fork lives in one place. + +import React from 'react'; +import * as fm from 'framer-motion'; + +const IS_WIN = typeof navigator !== 'undefined' && navigator.userAgent.includes('Windows'); + +const FRAMER_ONLY_PROPS = new Set([ + 'initial', 'animate', 'exit', 'transition', 'variants', 'layoutId', 'layout', + 'drag', 'dragConstraints', 'dragElastic', 'dragMomentum', 'dragControls', + 'dragDirectionLock', 'dragListener', 'dragTransition', 'dragSnapToOrigin', 'dragPropagation', + 'onDragStart', 'onDragEnd', 'onDrag', 'onDirectionLock', + 'onAnimationStart', 'onAnimationComplete', 'onUpdate', + 'onLayoutAnimationStart', 'onLayoutAnimationComplete', + 'whileHover', 'whileTap', 'whileFocus', 'whileDrag', 'whileInView', + 'viewport', 'transformTemplate', 'custom', 'inherit', +]); + +const stripFramerProps = (props: any) => { + const out: any = {}; + for (const k in props) { + if (!FRAMER_ONLY_PROPS.has(k)) out[k] = props[k]; + } + return out; +}; + +const motionShim: any = new Proxy({}, { + get: (_target, tag: string) => { + return React.forwardRef((props: any, ref: any) => + React.createElement(tag, { ...stripFramerProps(props), ref }) + ); + }, +}); + +export const motion: typeof fm.motion = IS_WIN ? motionShim : fm.motion; +export const AnimatePresence: typeof fm.AnimatePresence = IS_WIN + ? (({ children }: any) => children) as any + : fm.AnimatePresence; + +const animationControlsStub = { + start: () => Promise.resolve(), + stop: () => {}, + set: () => {}, + mount: () => () => {}, +}; +export const useAnimationControls: typeof fm.useAnimationControls = IS_WIN + ? (() => animationControlsStub as any) as any + : fm.useAnimationControls; diff --git a/frontend/src/app/components/Onboarding/ac/ACMultiChoice.tsx b/frontend/src/app/components/Onboarding/ac/ACMultiChoice.tsx index 40f3f5eb..fc5edf20 100644 --- a/frontend/src/app/components/Onboarding/ac/ACMultiChoice.tsx +++ b/frontend/src/app/components/Onboarding/ac/ACMultiChoice.tsx @@ -1,6 +1,6 @@ import React, { useLayoutEffect, useRef, useState } from 'react'; import { Box, Typography, ButtonBase } from '@mui/material'; -import { motion } from 'framer-motion'; +import { motion } from '../_motionWin'; import { useClaudeTokens } from '@/shared/styles/ThemeContext'; import { useCursorPosition } from './cursorStore'; import type { ACMultiChoiceOption } from '../steps/types'; diff --git a/frontend/src/app/components/Onboarding/ac/ACPopup.tsx b/frontend/src/app/components/Onboarding/ac/ACPopup.tsx index c79a94bd..8cedc55b 100644 --- a/frontend/src/app/components/Onboarding/ac/ACPopup.tsx +++ b/frontend/src/app/components/Onboarding/ac/ACPopup.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { Box, Typography } from '@mui/material'; -import { motion } from 'framer-motion'; +import { motion } from '../_motionWin'; import { useClaudeTokens } from '@/shared/styles/ThemeContext'; import { useCursorPosition } from './cursorStore'; diff --git a/frontend/src/app/components/Onboarding/ac/AgenticCursor.tsx b/frontend/src/app/components/Onboarding/ac/AgenticCursor.tsx index 831c18db..6a99c322 100644 --- a/frontend/src/app/components/Onboarding/ac/AgenticCursor.tsx +++ b/frontend/src/app/components/Onboarding/ac/AgenticCursor.tsx @@ -6,7 +6,7 @@ import React, { useState, } from 'react'; import { createPortal } from 'react-dom'; -import { motion, useAnimationControls, AnimatePresence } from 'framer-motion'; +import { motion, useAnimationControls, AnimatePresence } from '../_motionWin'; import { useClaudeTokens } from '@/shared/styles/ThemeContext'; import { cursorStore } from './cursorStore'; import { resolveSelector } from '../selectors'; diff --git a/frontend/src/app/components/feedback/ErrorSlime.tsx b/frontend/src/app/components/feedback/ErrorSlime.tsx index 979f99b3..f2978527 100644 --- a/frontend/src/app/components/feedback/ErrorSlime.tsx +++ b/frontend/src/app/components/feedback/ErrorSlime.tsx @@ -2,8 +2,6 @@ import React from 'react'; /** Slime illustration with X eyes and red badge for errors/warnings. */ export const ErrorSlime: React.FC<{ size?: number }> = ({ size = 22 }) => { - // eslint-disable-next-line no-console - console.log('[diag][ErrorSlime:render]', 'size=', size); return ( = ({ sessionId: sessionIdProp, onClose, embedded, autoFocus, isGlowing, onDismissGlow, initialContextPaths, onBranch }) => { - // eslint-disable-next-line no-console - console.log('[diag][AgentChat] render', { sessionIdProp, embedded }); const c = useClaudeTokens(); const STATUS_STYLES: Record = { running: { color: c.status.success, bg: c.status.successBg }, @@ -836,9 +834,6 @@ const AgentChat: React.FC = ({ sessionId: sessionIdProp, onClose const isActive = session.status === 'running' || session.status === 'waiting_approval' || session.status === 'draft'; const statusStyle = STATUS_STYLES[session.status] || { color: c.text.tertiary, bg: c.bg.secondary }; - // eslint-disable-next-line no-console - console.log('[diag][AgentChat:before-jsx]', id, 'status=', session.status, 'isActive=', isActive); - return ( diff --git a/frontend/src/app/pages/AgentChat/ChatInput.tsx b/frontend/src/app/pages/AgentChat/ChatInput.tsx index 1dea3b31..a9e60f10 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput.tsx @@ -43,8 +43,6 @@ interface Props { } const ChatInput = forwardRef(({ onSend, disabled, mode, onModeChange, model, onModelChange, provider, onProviderChange, isRunning, onStop, autoRunMode, contextEstimate, embedded, autoFocus, sessionId, queueLength = 0, thinkingLevel = 'auto', onThinkingLevelChange }, ref) => { - // eslint-disable-next-line no-console - console.log('[diag][ChatInput:render]', sessionId, 'mode=', mode, 'isRunning=', isRunning); const c = useClaudeTokens(); const editorRef = useRef(null); const containerRef = useRef(null); diff --git a/frontend/src/app/pages/AgentChat/ChatInput/model-picker/ModelPickerMenu.tsx b/frontend/src/app/pages/AgentChat/ChatInput/model-picker/ModelPickerMenu.tsx index 9f3275d6..232e06bc 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/model-picker/ModelPickerMenu.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/model-picker/ModelPickerMenu.tsx @@ -44,12 +44,6 @@ interface Props { } export const ModelPickerMenu: React.FC = (props) => { - // eslint-disable-next-line no-console - console.log('[diag][ModelPickerMenu:render]', 'model=', props.model, 'open=', !!props.modelAnchor); - React.useEffect(() => { - // eslint-disable-next-line no-console - console.log('[diag][ModelPickerMenu:committed]'); - }); const { c, menuPaperProps, modelAnchor, setModelAnchor, model, onModelChange, onProviderChange, modelSearchRef, modelSearch, setModelSearch, pushRecentModel, pushRecentSearch, diff --git a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ChatInputToolbar.tsx b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ChatInputToolbar.tsx index 213c912b..d9e661d6 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ChatInputToolbar.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ChatInputToolbar.tsx @@ -51,12 +51,6 @@ interface Props { } export const ChatInputToolbar: React.FC = (p) => { - // eslint-disable-next-line no-console - console.log('[diag][ChatInputToolbar:render]', p.sessionId); - React.useEffect(() => { - // eslint-disable-next-line no-console - console.log('[diag][ChatInputToolbar:committed]'); - }); const { c, modeConf, modesArr, mode, onModeChange, iconMap, modeAnchor, setModeAnchor, modelAnchor, setModelAnchor, thinkingAnchor, setThinkingAnchor, diff --git a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ContextRing.tsx b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ContextRing.tsx index 9bdadcc9..0eea0bda 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ContextRing.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ContextRing.tsx @@ -4,8 +4,6 @@ import Tooltip from '@mui/material/Tooltip'; import { formatTokenCount } from '../helpers'; export const ContextRing: React.FC<{ used: number; limit: number; accentColor: string; trackColor: string }> = ({ used, limit, accentColor, trackColor }) => { - // eslint-disable-next-line no-console - console.log('[diag][ContextRing:render]', 'used=', used, 'limit=', limit); if (used === 0) return null; const pct = Math.min((used / limit) * 100, 100); const size = 20; diff --git a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ModeControl.tsx b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ModeControl.tsx index fab1124a..0dbfeda4 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ModeControl.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ModeControl.tsx @@ -28,12 +28,6 @@ interface Props { export const ModeControl: React.FC = ({ c, menuPaperProps, modeConf, modesArr, mode, onModeChange, iconMap, modeAnchor, setModeAnchor, setModelAnchor, allModelFlat, model, }) => { - // eslint-disable-next-line no-console - console.log('[diag][ModeControl:render]', 'mode=', mode); - React.useEffect(() => { - // eslint-disable-next-line no-console - console.log('[diag][ModeControl:committed]'); - }); return ( <> = ({ c, model, allModelFlat, thinkingLevel, onThinkingLevelChange, thinkingAnchor, setThinkingAnchor, menuPaperProps, }) => { - // eslint-disable-next-line no-console - console.log('[diag][ThinkingLevelControl:render]', 'model=', model, 'level=', thinkingLevel); - React.useEffect(() => { - // eslint-disable-next-line no-console - console.log('[diag][ThinkingLevelControl:committed]'); - }); const currentModel = allModelFlat.find((m: any) => m.value === model) as any; if (!currentModel?.reasoning || !onThinkingLevelChange) return null; const levels: Array<{ value: ThinkingLevel; label: string; desc: string }> = [ diff --git a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ToolbarActions.tsx b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ToolbarActions.tsx index 80bee944..c0b92e20 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ToolbarActions.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ToolbarActions.tsx @@ -33,12 +33,6 @@ export const ToolbarActions: React.FC = ({ c, elementSelection, autoRunMode, ownerId, sessionId, generalFileInputRef, addImageFiles, uploadAndAttachFiles, hasContent, disabled, isRunning, onStop, handleSend, }) => { - // eslint-disable-next-line no-console - console.log('[diag][ToolbarActions:render]', sessionId, 'isRunning=', isRunning); - React.useEffect(() => { - // eslint-disable-next-line no-console - console.log('[diag][ToolbarActions:committed]'); - }); return ( <> {elementSelection && !autoRunMode && (() => { diff --git a/frontend/src/app/pages/AgentChat/ChatInput/view/AttachmentChips.tsx b/frontend/src/app/pages/AgentChat/ChatInput/view/AttachmentChips.tsx index 436f7d4c..695c9e0b 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/view/AttachmentChips.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/view/AttachmentChips.tsx @@ -43,8 +43,6 @@ export const AttachmentChips: React.FC = ({ forcedTools, setForcedTools, selectedElements, elementSelection, ownerId, }) => { - // eslint-disable-next-line no-console - console.log('[diag][AttachmentChips:render]', 'images=', images.length, 'paths=', contextPaths.length, 'tools=', forcedTools.length); return ( <> {images.length > 0 && ( diff --git a/frontend/src/app/pages/AgentChat/ChatInput/view/ChatInputOverlays.tsx b/frontend/src/app/pages/AgentChat/ChatInput/view/ChatInputOverlays.tsx index 549dc99b..d73f13d0 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/view/ChatInputOverlays.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/view/ChatInputOverlays.tsx @@ -25,8 +25,6 @@ export const ChatInputOverlays: React.FC = ({ c, lightboxSrc, setLightboxSrc, oversizeQueue, summarizingPath, summarizeOversize, detachOversize, currentModelCtx, summarizeError, setSummarizeError, }) => { - // eslint-disable-next-line no-console - console.log('[diag][ChatInputOverlays:render]', 'lightbox=', !!lightboxSrc, 'oversize=', oversizeQueue && oversizeQueue.length); return ( <> = (p) => { - // eslint-disable-next-line no-console - console.log('[diag][ChatInputView:render]', p.sessionId); const { c } = p; return ( = ({ c, editorRef, disabled, hasContent, hasAttachments, autoRunMode, isRunning, queueLength, placeholderLabel, onInput, onClick, onKeyDown, onPaste, }) => { - // eslint-disable-next-line no-console - console.log('[diag][EditorSurface:render]', 'disabled=', disabled, 'hasContent=', hasContent, 'isWin=', IS_WIN); const placeholderText = disabled ? 'Agent is working...' : autoRunMode diff --git a/frontend/src/app/pages/AgentChat/ChatInput/view/SendBlockBanner.tsx b/frontend/src/app/pages/AgentChat/ChatInput/view/SendBlockBanner.tsx index 59ee9023..ef82bf25 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/view/SendBlockBanner.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/view/SendBlockBanner.tsx @@ -16,8 +16,6 @@ interface Props { } export const SendBlockBanner: React.FC = ({ sendBlock, c, sessionId, setSendBlock, setContextPaths, setModelAnchor }) => { - // eslint-disable-next-line no-console - console.log('[diag][SendBlockBanner:render]', sessionId); const fmt = (n: number) => n >= 1000 ? `${(n / 1000).toFixed(1)}K` : String(n); const over = sendBlock.estimate - sendBlock.window; return ( diff --git a/frontend/src/app/pages/AgentChat/bubbles/CompactionMarker.tsx b/frontend/src/app/pages/AgentChat/bubbles/CompactionMarker.tsx index 303daa86..d5907e05 100644 --- a/frontend/src/app/pages/AgentChat/bubbles/CompactionMarker.tsx +++ b/frontend/src/app/pages/AgentChat/bubbles/CompactionMarker.tsx @@ -6,8 +6,6 @@ import { useClaudeTokens } from '@/shared/styles/ThemeContext'; /** Chip marking where auto-compaction collapsed older turns, so the transcript doesn't just appear to skip. */ const CompactionMarker: React.FC<{ collapsedCount: number }> = ({ collapsedCount }) => { - // eslint-disable-next-line no-console - console.log('[diag][CompactionMarker:render]', 'collapsed=', collapsedCount); const c = useClaudeTokens(); const label = collapsedCount > 0 ? `${collapsedCount} earlier turn${collapsedCount === 1 ? '' : 's'} summarized` diff --git a/frontend/src/app/pages/AgentChat/bubbles/MessageBubble.tsx b/frontend/src/app/pages/AgentChat/bubbles/MessageBubble.tsx index f0f2ec45..8c79e7fd 100644 --- a/frontend/src/app/pages/AgentChat/bubbles/MessageBubble.tsx +++ b/frontend/src/app/pages/AgentChat/bubbles/MessageBubble.tsx @@ -844,8 +844,6 @@ interface Props { } const MessageBubble: React.FC = React.memo(({ message, editing = false, onSaveEdit, onCancelEdit, isStreaming, dynamicTurnLabel }) => { - // eslint-disable-next-line no-console - console.log('[diag][MessageBubble:render]', message && message.id, 'role=', message && message.role, 'streaming=', isStreaming); const c = useClaudeTokens(); const dispatch = useAppDispatch(); const [editText, setEditText] = useState(''); diff --git a/frontend/src/app/pages/AgentChat/bubbles/StreamingBubble.tsx b/frontend/src/app/pages/AgentChat/bubbles/StreamingBubble.tsx index 823ff30e..f4b4c0c5 100644 --- a/frontend/src/app/pages/AgentChat/bubbles/StreamingBubble.tsx +++ b/frontend/src/app/pages/AgentChat/bubbles/StreamingBubble.tsx @@ -12,8 +12,6 @@ interface Props { /** Leaf subscriber for one session's streaming entry; isolates re-renders so AgentChat doesn't churn per character. */ const StreamingBubble: React.FC = ({ sessionId, activeBranchId, turnLabel, onStreamGrew }) => { - // eslint-disable-next-line no-console - console.log('[diag][StreamingBubble:render]', sessionId, 'branch=', activeBranchId); const streamingMessage = useStreamingMessage(sessionId); const typedContent = streamingMessage?.content ?? ''; // RAF-coalesce so onStreamGrew fires once per frame regardless of token rate. diff --git a/frontend/src/app/pages/AgentChat/shell/ApprovalBar.tsx b/frontend/src/app/pages/AgentChat/shell/ApprovalBar.tsx index 276f42a9..484c3819 100644 --- a/frontend/src/app/pages/AgentChat/shell/ApprovalBar.tsx +++ b/frontend/src/app/pages/AgentChat/shell/ApprovalBar.tsx @@ -899,8 +899,6 @@ const GenericApprovalBar: React.FC = ({ request, onApprove, onDeny }) => }; const ApprovalBar: React.FC = (props) => { - // eslint-disable-next-line no-console - console.log('[diag][ApprovalBar:render]', props.request && props.request.tool_name); if (props.request.tool_name === 'AskUserQuestion') { return ; } diff --git a/frontend/src/app/pages/AgentChat/shell/ContextDrawer.tsx b/frontend/src/app/pages/AgentChat/shell/ContextDrawer.tsx index 2c480238..a6eeda15 100644 --- a/frontend/src/app/pages/AgentChat/shell/ContextDrawer.tsx +++ b/frontend/src/app/pages/AgentChat/shell/ContextDrawer.tsx @@ -9,8 +9,6 @@ import { useClaudeTokens } from '@/shared/styles/ThemeContext'; /** /context drawer: shows session MCPs, ctx%, cache hits, compaction. Opened via window CustomEvent from ChatInput's slash handler. */ export default function ContextDrawer() { - // eslint-disable-next-line no-console - console.log('[diag][ContextDrawer:render]'); const c = useClaudeTokens(); const [openFor, setOpenFor] = useState(null); const session = useAppSelector((state) => (openFor ? state.agents.sessions[openFor] : undefined)); diff --git a/frontend/src/app/pages/AgentChat/shell/MessageActionBar.tsx b/frontend/src/app/pages/AgentChat/shell/MessageActionBar.tsx index f3d3699f..0530c4a8 100644 --- a/frontend/src/app/pages/AgentChat/shell/MessageActionBar.tsx +++ b/frontend/src/app/pages/AgentChat/shell/MessageActionBar.tsx @@ -44,8 +44,6 @@ const MessageActionBar: React.FC = ({ onBranch, branchNav, }) => { - // eslint-disable-next-line no-console - console.log('[diag][MessageActionBar:render]', 'role=', role); const c = useClaudeTokens(); const [copied, setCopied] = useState(false); diff --git a/frontend/src/app/pages/AgentChat/tool-bubbles/ToolCallBubble.tsx b/frontend/src/app/pages/AgentChat/tool-bubbles/ToolCallBubble.tsx index 332d611b..8c15077f 100644 --- a/frontend/src/app/pages/AgentChat/tool-bubbles/ToolCallBubble.tsx +++ b/frontend/src/app/pages/AgentChat/tool-bubbles/ToolCallBubble.tsx @@ -47,8 +47,6 @@ interface ToolCallBubbleProps { const ToolCallBubble: React.FC = React.memo( ({ call, result = null, isPending = false, isStreaming = false, mcpCompact = false, sessionId }) => { - // eslint-disable-next-line no-console - console.log('[diag][ToolCallBubble:render]', call && call.id, 'name=', call && call.name); ensureToolCallKeyframes(); const c = useClaudeTokens(); diff --git a/frontend/src/app/pages/AgentChat/tool-bubbles/ToolGroupBubble.tsx b/frontend/src/app/pages/AgentChat/tool-bubbles/ToolGroupBubble.tsx index c1c49eb3..0c4de468 100644 --- a/frontend/src/app/pages/AgentChat/tool-bubbles/ToolGroupBubble.tsx +++ b/frontend/src/app/pages/AgentChat/tool-bubbles/ToolGroupBubble.tsx @@ -70,8 +70,6 @@ interface Props { } const ToolGroupBubble: React.FC = React.memo(({ group, isSessionRunning = false, meta, sessionId }) => { - // eslint-disable-next-line no-console - console.log('[diag][ToolGroupBubble:render]', group && group.id, 'mcp=', !!(group && group.mcpServer), 'items=', group && group.items && group.items.length); const c = useClaudeTokens(); const isMcp = !!group.mcpServer; const [expanded, setExpanded] = useState(isMcp); diff --git a/frontend/src/app/pages/Dashboard/cards/BrowserCard.tsx b/frontend/src/app/pages/Dashboard/cards/BrowserCard.tsx index 435d4052..a2d68b54 100644 --- a/frontend/src/app/pages/Dashboard/cards/BrowserCard.tsx +++ b/frontend/src/app/pages/Dashboard/cards/BrowserCard.tsx @@ -75,8 +75,6 @@ const HANDLE_DEFS: { dir: ResizeDir; sx: Record }[] = [ // On Windows, force iframe fallback path: the tag mount segfaults the renderer during commit on Chromium 144 + this Electron 40 CastLabs build. iframe renders blank for sites with X-Frame-Options but does not crash. Mac keeps webview (full browser). const isElectron = navigator.userAgent.includes('Electron') && !navigator.userAgent.includes('Windows'); -// eslint-disable-next-line no-console -console.log('[diag][BrowserCard] isElectron=', isElectron, 'ua=', navigator.userAgent, 'hasOpenswarm=', !!(window as any).openswarm); const chromeUserAgent = navigator.userAgent .replace(/\s*Electron\/\S+/, '') @@ -127,8 +125,6 @@ const BrowserCard: React.FC = ({ isSelected = false, isHighlighted = false, multiDragDelta, onCardSelect, onDragStart, onDragMove, onDragEnd, cardZOrder = 0, onDoubleClick, onBringToFront, }) => { - // eslint-disable-next-line no-console - console.log('[diag][BrowserCard:render]', browserId, 'tabs=', tabs && tabs.length); const c = useClaudeTokens(); const dispatch = useAppDispatch(); const scrollOverlayRef = useOverlayScrollPassthrough(isSelected); @@ -1123,34 +1119,11 @@ const BrowserCard: React.FC = ({ style={{ width: '100%', height: '100%', border: 'none' }} title="Browser" referrerPolicy="no-referrer-when-downgrade" - onLoad={() => { - // eslint-disable-next-line no-console - console.log('[diag][iframe:onLoad]', activeUrl); - }} onError={(e) => { // eslint-disable-next-line no-console console.error('[diag][iframe:onError]', activeUrl, (e as any)?.message || e); }} /> - - - iframe mode: some sites may not load. Use the Electron build for full browser support. - - )} diff --git a/frontend/src/app/pages/Workflows/WorkflowCard.tsx b/frontend/src/app/pages/Workflows/WorkflowCard.tsx index 59a8d967..83412190 100644 --- a/frontend/src/app/pages/Workflows/WorkflowCard.tsx +++ b/frontend/src/app/pages/Workflows/WorkflowCard.tsx @@ -97,8 +97,6 @@ const WorkflowCard: React.FC = ({ isSelected = false, isHighlighted = false, multiDragDelta, onCardSelect, onDragStart, onDragMove, onDragEnd, onDoubleClick, onBringToFront, }) => { - // eslint-disable-next-line no-console - console.log('[diag][WorkflowCard:render]', workflowId); const c = useClaudeTokens(); const dispatch = useAppDispatch(); diff --git a/frontend/src/shared/state/agentsSlice.ts b/frontend/src/shared/state/agentsSlice.ts index 16073b2d..40b29305 100644 --- a/frontend/src/shared/state/agentsSlice.ts +++ b/frontend/src/shared/state/agentsSlice.ts @@ -291,19 +291,13 @@ export const fetchSession = createAsyncThunk( export const launchAndSendFirstMessage = createAsyncThunk( 'agents/launchAndSendFirstMessage', async ({ draftId, config, prompt, mode, model, provider, images, contextPaths, forcedTools, attachedSkills, selectedBrowserIds }: LaunchAndSendPayload) => { - // eslint-disable-next-line no-console - console.log('[diag][thunk] launchAndSendFirstMessage START draft=', draftId, 'mode=', mode, 'model=', model, 'provider=', provider); const launchRes = await fetch(`${AGENTS_API}/launch`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(config), }); - // eslint-disable-next-line no-console - console.log('[diag][thunk] launch fetch ok=', launchRes.ok, 'status=', launchRes.status); const launchData = await launchRes.json(); const session = launchData.session as AgentSession; - // eslint-disable-next-line no-console - console.log('[diag][thunk] launch parsed, sessionId=', session && session.id); await fetch(`${AGENTS_API}/sessions/${session.id}/message`, { method: 'POST', @@ -476,15 +470,9 @@ export const searchHistory = createAsyncThunk( export const resumeSession = createAsyncThunk( 'agents/resumeSession', async ({ sessionId }: { sessionId: string }) => { - // eslint-disable-next-line no-console - console.log('[diag][thunk] resumeSession START', sessionId); try { const res = await fetch(`${AGENTS_API}/sessions/${sessionId}/resume`, { method: 'POST' }); - // eslint-disable-next-line no-console - console.log('[diag][thunk] resumeSession fetch ok=', res.ok, 'status=', res.status); const data = await res.json(); - // eslint-disable-next-line no-console - console.log('[diag][thunk] resumeSession parsed, keys=', Object.keys(data || {}).join(',')); return data.session as AgentSession; } catch (e: any) { // eslint-disable-next-line no-console diff --git a/frontend/src/shared/state/settingsSlice.ts b/frontend/src/shared/state/settingsSlice.ts index 750c77d3..d639f6a3 100644 --- a/frontend/src/shared/state/settingsSlice.ts +++ b/frontend/src/shared/state/settingsSlice.ts @@ -115,7 +115,7 @@ const initialState: SettingsState = { theme: 'dark', new_agent_shortcut: 'Meta+l', anthropic_api_key: null, - browser_homepage: 'https://www.google.com', + browser_homepage: 'https://duckduckgo.com', auto_select_mode_on_new_agent: false, expand_new_chats_in_dashboard: false, auto_reveal_sub_agents: true, diff --git a/frontend/src/shared/ws/WebSocketManager.ts b/frontend/src/shared/ws/WebSocketManager.ts index 44f7cac5..35a8edc5 100644 --- a/frontend/src/shared/ws/WebSocketManager.ts +++ b/frontend/src/shared/ws/WebSocketManager.ts @@ -192,8 +192,6 @@ class WebSocketManager { const token = _getAuthTokenSafe(); const sep = this.url.includes('?') ? '&' : '?'; const urlWithToken = token ? `${this.url}${sep}token=${encodeURIComponent(token)}` : this.url; - // eslint-disable-next-line no-console - console.log('[diag][ws] connect', this.url, 'sessionId=', this.sessionId, 'hasToken=', !!token); this.ws = new WebSocket(urlWithToken); this.ws.onopen = () => {