diff --git a/package-lock.json b/package-lock.json index 44e810d7..d2507f5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "react-markdown": "^10.1.0", "react-syntax-highlighter": "^16.1.0", "rehype-raw": "^7.0.0", + "rehype-slug": "^6.0.0", "remark-frontmatter": "^5.0.0", "remark-gfm": "^4.0.1", "ws": "^8.16.0" @@ -9929,6 +9930,12 @@ "dev": true, "license": "MIT" }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -10223,6 +10230,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-heading-rank": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-parse-selector": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", @@ -10331,6 +10351,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -15317,6 +15350,23 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "github-slugger": "^2.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-frontmatter": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", diff --git a/package.json b/package.json index 34cf7e76..fd5abb3e 100644 --- a/package.json +++ b/package.json @@ -232,6 +232,7 @@ "react-markdown": "^10.1.0", "react-syntax-highlighter": "^16.1.0", "rehype-raw": "^7.0.0", + "rehype-slug": "^6.0.0", "remark-frontmatter": "^5.0.0", "remark-gfm": "^4.0.1", "ws": "^8.16.0" diff --git a/src/main/ipc/handlers/persistence.ts b/src/main/ipc/handlers/persistence.ts index 203c495a..52b60efc 100644 --- a/src/main/ipc/handlers/persistence.ts +++ b/src/main/ipc/handlers/persistence.ts @@ -136,10 +136,11 @@ export function registerPersistenceHandlers(deps: PersistenceHandlerDependencies for (const session of sessions) { const prevSession = previousSessionMap.get(session.id); if (prevSession) { - // Session exists - check if state changed + // Session exists - check if state or other tracked properties changed if (prevSession.state !== session.state || prevSession.inputMode !== session.inputMode || prevSession.name !== session.name || + prevSession.cwd !== session.cwd || JSON.stringify(prevSession.cliActivity) !== JSON.stringify(session.cliActivity)) { webServer.broadcastSessionStateChange(session.id, session.state, { name: session.name, diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index fce3e8d3..964653a6 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -1005,16 +1005,20 @@ function MaestroConsoleInner() { } // Check if a session already exists for this worktree - const existingSession = sessions.find(s => - (s.parentSessionId === parentSession.id && s.worktreeBranch === subdir.branch) || - s.cwd === subdir.path - ); + // Normalize paths for comparison (remove trailing slashes) + const normalizedSubdirPath = subdir.path.replace(/\/+$/, ''); + const existingSession = sessions.find(s => { + const normalizedCwd = s.cwd.replace(/\/+$/, ''); + // Check if same path (regardless of parent) or same branch under same parent + return normalizedCwd === normalizedSubdirPath || + (s.parentSessionId === parentSession.id && s.worktreeBranch === subdir.branch); + }); if (existingSession) { continue; } // Also check in sessions we're about to add - if (newWorktreeSessions.some(s => s.cwd === subdir.path)) { + if (newWorktreeSessions.some(s => s.cwd.replace(/\/+$/, '') === normalizedSubdirPath)) { continue; } @@ -3311,6 +3315,7 @@ function MaestroConsoleInner() { batchRunStates: _batchRunStates, getBatchState, activeBatchSessionIds, + stoppingBatchSessionIds, startBatchRun, stopBatchRun, // Error handling (Phase 5.10) @@ -3532,17 +3537,7 @@ function MaestroConsoleInner() { // This is session-specific so users can edit docs in other sessions while one runs // Quick Win 4: Memoized to prevent unnecessary re-calculations const currentSessionBatchState = useMemo(() => { - const state = activeSession ? getBatchState(activeSession.id) : null; - // DEBUG: Log currentSessionBatchState computation - if (state) { - console.log('[App:currentSessionBatchState] Computed:', { - sessionId: activeSession?.id, - loopIteration: state.loopIteration, - completedTasksAcrossAllDocs: state.completedTasksAcrossAllDocs, - totalTasksAcrossAllDocs: state.totalTasksAcrossAllDocs, - }); - } - return state; + return activeSession ? getBatchState(activeSession.id) : null; }, [activeSession, getBatchState]); // Get batch state for display - prioritize the session with an active batch run, @@ -3800,10 +3795,14 @@ function MaestroConsoleInner() { if (!parentSession) return; // Check if session already exists for this worktree - const existingSession = currentSessions.find(s => - (s.parentSessionId === sessionId && s.worktreeBranch === worktree.branch) || - s.cwd === worktree.path - ); + // Normalize paths for comparison (remove trailing slashes) + const normalizedWorktreePath = worktree.path.replace(/\/+$/, ''); + const existingSession = currentSessions.find(s => { + const normalizedCwd = s.cwd.replace(/\/+$/, ''); + // Check if same path (regardless of parent) or same branch under same parent + return normalizedCwd === normalizedWorktreePath || + (s.parentSessionId === sessionId && s.worktreeBranch === worktree.branch); + }); if (existingSession) return; // Create new worktree session @@ -8444,6 +8443,7 @@ function MaestroConsoleInner() { )); }} activeBatchSessionIds={activeBatchSessionIds} + stoppingBatchSessionIds={stoppingBatchSessionIds} showSessionJumpNumbers={showSessionJumpNumbers} visibleSessions={visibleSessions} autoRunStats={autoRunStats} diff --git a/src/renderer/components/AutoRun.tsx b/src/renderer/components/AutoRun.tsx index 3ed26cc0..25e487b8 100644 --- a/src/renderer/components/AutoRun.tsx +++ b/src/renderer/components/AutoRun.tsx @@ -1,6 +1,7 @@ import React, { useState, useRef, useEffect, useLayoutEffect, useCallback, memo, useMemo, forwardRef, useImperativeHandle } from 'react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; +import rehypeSlug from 'rehype-slug'; import { Eye, Edit, Play, Square, HelpCircle, Loader2, Image, X, Search, ChevronDown, ChevronRight, FolderOpen, FileText, RefreshCw, Maximize2, AlertTriangle, SkipForward, XCircle } from 'lucide-react'; import { getEncoder, formatTokenCount } from '../utils/tokenCounter'; import type { BatchRunState, SessionState, Theme, Shortcut } from '../types'; @@ -1142,6 +1143,8 @@ const AutoRunInner = forwardRef(function AutoRunInn onFileClick: handleFileClick, // Open external links in system browser onExternalLinkClick: (href) => window.maestro.shell.openExternal(href), + // Provide container ref for anchor link scrolling + containerRef: previewRef, // Add search highlighting when search is active with matches searchHighlight: searchOpen && searchQuery.trim() && totalMatches > 0 ? { @@ -1614,6 +1617,7 @@ const AutoRunInner = forwardRef(function AutoRunInn {localContent || '*No content yet. Switch to Edit mode to start writing.*'} diff --git a/src/renderer/components/FilePreview.tsx b/src/renderer/components/FilePreview.tsx index 5c309ed4..c87caa13 100644 --- a/src/renderer/components/FilePreview.tsx +++ b/src/renderer/components/FilePreview.tsx @@ -2,6 +2,7 @@ import React, { useState, useRef, useEffect, useMemo, useCallback } from 'react' import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import rehypeRaw from 'rehype-raw'; +import rehypeSlug from 'rehype-slug'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'; import { FileCode, X, Eye, ChevronUp, ChevronDown, ChevronLeft, ChevronRight, Clipboard, Loader2, Image, Globe, Save, Edit, FolderOpen, AlertTriangle } from 'lucide-react'; @@ -1534,7 +1535,7 @@ export function FilePreview({ file, onClose, theme, markdownEditMode, setMarkdow ? [[remarkFileLinks, { fileTree, cwd }] as any] : []) ]} - rehypePlugins={[rehypeRaw]} + rehypePlugins={[rehypeRaw, rehypeSlug]} components={{ a: ({ node: _node, href, children, ...props }) => { // Check for maestro-file:// protocol OR data-maestro-file attribute @@ -1543,6 +1544,10 @@ export function FilePreview({ file, onClose, theme, markdownEditMode, setMarkdow const isMaestroFile = href?.startsWith('maestro-file://') || !!dataFilePath; const filePath = dataFilePath || (href?.startsWith('maestro-file://') ? href.replace('maestro-file://', '') : null); + // Check for anchor links (same-page navigation) + const isAnchorLink = href?.startsWith('#') ?? false; + const anchorId = isAnchorLink && href ? href.slice(1) : null; + return ( ( disabled={isCurrentSessionStopping} className={`flex items-center gap-1.5 px-3.5 py-1.5 rounded-lg font-bold text-xs transition-all ${isCurrentSessionStopping ? 'cursor-not-allowed' : 'hover:opacity-90 cursor-pointer'}`} style={{ - backgroundColor: theme.colors.error, - color: 'white' + backgroundColor: isCurrentSessionStopping ? theme.colors.warning : theme.colors.error, + color: isCurrentSessionStopping ? theme.colors.bgMain : 'white', + pointerEvents: isCurrentSessionStopping ? 'none' : 'auto' }} title={isCurrentSessionStopping ? 'Stopping after current task...' : 'Click to stop batch run'} > diff --git a/src/renderer/components/MermaidRenderer.tsx b/src/renderer/components/MermaidRenderer.tsx index 224ba78c..dc2164eb 100644 --- a/src/renderer/components/MermaidRenderer.tsx +++ b/src/renderer/components/MermaidRenderer.tsx @@ -1,17 +1,170 @@ import { useEffect, useRef, useState } from 'react'; import mermaid from 'mermaid'; import DOMPurify from 'dompurify'; +import type { Theme } from '../types'; interface MermaidRendererProps { chart: string; - theme: any; + theme: Theme; } -// Initialize mermaid with custom theme settings -const initMermaid = (isDarkTheme: boolean) => { +/** + * Convert hex color to RGB components + */ +function hexToRgb(hex: string): { r: number; g: number; b: number } | null { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; +} + +/** + * Create a slightly lighter/darker version of a color + */ +function adjustBrightness(hex: string, percent: number): string { + const rgb = hexToRgb(hex); + if (!rgb) return hex; + + const adjust = (value: number) => Math.min(255, Math.max(0, Math.round(value + (255 * percent / 100)))); + const r = adjust(rgb.r); + const g = adjust(rgb.g); + const b = adjust(rgb.b); + + return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`; +} + +/** + * Initialize mermaid with theme-aware settings using the app's color scheme + */ +const initMermaid = (theme: Theme) => { + const colors = theme.colors; + + // Determine if this is a dark theme by checking background luminance + const bgRgb = hexToRgb(colors.bgMain); + const isDark = bgRgb ? (bgRgb.r * 0.299 + bgRgb.g * 0.587 + bgRgb.b * 0.114) < 128 : true; + + // Create theme variables from the app's color scheme + const themeVariables = { + // Base colors + primaryColor: colors.accent, + primaryTextColor: colors.textMain, + primaryBorderColor: colors.border, + + // Secondary colors (derived from accent) + secondaryColor: adjustBrightness(colors.accent, isDark ? -20 : 20), + secondaryTextColor: colors.textMain, + secondaryBorderColor: colors.border, + + // Tertiary colors + tertiaryColor: colors.bgActivity, + tertiaryTextColor: colors.textMain, + tertiaryBorderColor: colors.border, + + // Background and text + background: colors.bgMain, + mainBkg: colors.bgActivity, + textColor: colors.textMain, + titleColor: colors.textMain, + + // Line colors + lineColor: colors.textDim, + + // Node colors for flowcharts + nodeBkg: colors.bgActivity, + nodeTextColor: colors.textMain, + nodeBorder: colors.border, + + // Cluster (subgraph) colors + clusterBkg: colors.bgSidebar, + clusterBorder: colors.border, + + // Edge labels + edgeLabelBackground: colors.bgMain, + + // State diagram colors + labelColor: colors.textMain, + altBackground: colors.bgSidebar, + + // Sequence diagram colors + actorBkg: colors.bgActivity, + actorBorder: colors.border, + actorTextColor: colors.textMain, + actorLineColor: colors.textDim, + signalColor: colors.textMain, + signalTextColor: colors.textMain, + labelBoxBkgColor: colors.bgActivity, + labelBoxBorderColor: colors.border, + labelTextColor: colors.textMain, + loopTextColor: colors.textMain, + noteBkgColor: colors.bgActivity, + noteBorderColor: colors.border, + noteTextColor: colors.textMain, + activationBkgColor: colors.bgActivity, + activationBorderColor: colors.accent, + sequenceNumberColor: colors.textMain, + + // Class diagram colors + classText: colors.textMain, + + // Git graph colors + git0: colors.accent, + git1: colors.success, + git2: colors.warning, + git3: colors.error, + gitBranchLabel0: colors.textMain, + gitBranchLabel1: colors.textMain, + gitBranchLabel2: colors.textMain, + gitBranchLabel3: colors.textMain, + + // Gantt colors + sectionBkgColor: colors.bgActivity, + altSectionBkgColor: colors.bgSidebar, + sectionBkgColor2: colors.bgActivity, + taskBkgColor: colors.accent, + taskTextColor: colors.textMain, + taskTextLightColor: colors.textMain, + taskTextOutsideColor: colors.textMain, + activeTaskBkgColor: colors.accent, + activeTaskBorderColor: colors.border, + doneTaskBkgColor: colors.success, + doneTaskBorderColor: colors.border, + critBkgColor: colors.error, + critBorderColor: colors.error, + gridColor: colors.border, + todayLineColor: colors.warning, + + // Pie chart colors + pie1: colors.accent, + pie2: colors.success, + pie3: colors.warning, + pie4: colors.error, + pie5: adjustBrightness(colors.accent, 30), + pie6: adjustBrightness(colors.success, 30), + pie7: adjustBrightness(colors.warning, 30), + pieTitleTextColor: colors.textMain, + pieSectionTextColor: colors.textMain, + pieLegendTextColor: colors.textMain, + + // Relationship colors for ER diagrams + relationColor: colors.textDim, + relationLabelColor: colors.textMain, + relationLabelBackground: colors.bgMain, + + // Requirement diagram + requirementBkgColor: colors.bgActivity, + requirementBorderColor: colors.border, + requirementTextColor: colors.textMain, + + // Mindmap + mindmapBkg: colors.bgActivity, + }; + mermaid.initialize({ startOnLoad: false, - theme: isDarkTheme ? 'dark' : 'default', + theme: 'base', // Use 'base' theme to fully customize with themeVariables + themeVariables, securityLevel: 'strict', fontFamily: 'ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace', flowchart: { @@ -56,13 +209,8 @@ export function MermaidRenderer({ chart, theme }: MermaidRendererProps) { setIsLoading(true); setError(null); - // Determine if theme is dark by checking background color - const isDarkTheme = theme.colors.bgMain.toLowerCase().includes('#1') || - theme.colors.bgMain.toLowerCase().includes('#2') || - theme.colors.bgMain.toLowerCase().includes('#0'); - - // Initialize mermaid with the current theme - initMermaid(isDarkTheme); + // Initialize mermaid with the app's theme colors + initMermaid(theme); try { // Generate a unique ID for this diagram @@ -100,7 +248,7 @@ export function MermaidRenderer({ chart, theme }: MermaidRendererProps) { }; renderChart(); - }, [chart, theme.colors.bgMain]); + }, [chart, theme]); if (isLoading) { return ( diff --git a/src/renderer/components/SessionItem.tsx b/src/renderer/components/SessionItem.tsx index 5dc7b12d..d625aec2 100644 --- a/src/renderer/components/SessionItem.tsx +++ b/src/renderer/components/SessionItem.tsx @@ -34,6 +34,7 @@ export interface SessionItemProps { groupId?: string; // The group ID context for generating editing key gitFileCount?: number; isInBatch?: boolean; + isBatchStopping?: boolean; // Whether the batch is in stopping state jumpNumber?: string | null; // Session jump shortcut number (1-9, 0) // Handlers @@ -74,6 +75,7 @@ export const SessionItem = memo(function SessionItem({ groupId, gitFileCount, isInBatch = false, + isBatchStopping = false, jumpNumber, onSelect, onDragStart, @@ -210,12 +212,15 @@ export const SessionItem = memo(function SessionItem({ {/* AUTO Mode Indicator */} {isInBatch && (
- AUTO + {isBatchStopping ? 'STOPPING' : 'AUTO'}
)} diff --git a/src/renderer/components/SessionList.tsx b/src/renderer/components/SessionList.tsx index 23a36373..e831b88b 100644 --- a/src/renderer/components/SessionList.tsx +++ b/src/renderer/components/SessionList.tsx @@ -495,6 +495,8 @@ interface SessionTooltipContentProps { theme: Theme; gitFileCount?: number; groupName?: string; // Optional group name (for skinny mode) + isInBatch?: boolean; // Whether session is running in auto mode + isBatchStopping?: boolean; // Whether batch is in stopping state } function SessionTooltipContent({ @@ -502,6 +504,8 @@ function SessionTooltipContent({ theme, gitFileCount, groupName, + isInBatch = false, + isBatchStopping = false, }: SessionTooltipContentProps) { return ( <> @@ -523,6 +527,19 @@ function SessionTooltipContent({ {session.isGitRepo ? 'GIT' : 'LOCAL'} )} + {/* AUTO Mode Indicator */} + {isInBatch && ( + + + {isBatchStopping ? 'STOPPING' : 'AUTO'} + + )}
{session.state} • {session.toolType}
@@ -686,6 +703,7 @@ interface SessionListProps { // Auto mode props activeBatchSessionIds?: string[]; // Session IDs that are running in auto mode + stoppingBatchSessionIds?: string[]; // Session IDs that are in stopping state // Session jump shortcut props (Opt+Cmd+NUMBER) showSessionJumpNumbers?: boolean; @@ -750,6 +768,7 @@ export function SessionList(props: SessionListProps) { onOpenWorktreeConfig, onDeleteWorktree, activeBatchSessionIds = [], + stoppingBatchSessionIds = [], showSessionJumpNumbers = false, visibleSessions = [], autoRunStats, @@ -984,6 +1003,8 @@ export function SessionList(props: SessionListProps) { session={s} theme={theme} gitFileCount={gitFileCounts.get(s.id)} + isInBatch={activeBatchSessionIds.includes(s.id)} + isBatchStopping={stoppingBatchSessionIds.includes(s.id)} /> @@ -1026,6 +1047,7 @@ export function SessionList(props: SessionListProps) { groupId={options.groupId} gitFileCount={gitFileCounts.get(session.id)} isInBatch={activeBatchSessionIds.includes(session.id)} + isBatchStopping={stoppingBatchSessionIds.includes(session.id)} jumpNumber={getSessionJumpNumber(session.id)} onSelect={() => setActiveSessionId(session.id)} onDragStart={() => handleDragStart(session.id)} @@ -1069,7 +1091,7 @@ export function SessionList(props: SessionListProps) { > {/* Worktree children list */}
- {worktreeChildren.sort((a, b) => compareSessionNames(a.worktreeBranch || a.name, b.worktreeBranch || b.name)).map(child => { + {worktreeChildren.sort((a, b) => compareSessionNames(a.name, b.name)).map(child => { const childGlobalIdx = sortedSessions.findIndex(s => s.id === child.id); const isChildKeyboardSelected = activeFocus === 'sidebar' && childGlobalIdx === selectedSidebarIndex; return ( @@ -1085,6 +1107,7 @@ export function SessionList(props: SessionListProps) { leftSidebarOpen={leftSidebarOpen} gitFileCount={gitFileCounts.get(child.id)} isInBatch={activeBatchSessionIds.includes(child.id)} + isBatchStopping={stoppingBatchSessionIds.includes(child.id)} jumpNumber={getSessionJumpNumber(child.id)} onSelect={() => setActiveSessionId(child.id)} onDragStart={() => handleDragStart(child.id)} @@ -2017,14 +2040,16 @@ export function SessionList(props: SessionListProps) {
{sortedSessions.map(session => { const isInBatch = activeBatchSessionIds.includes(session.id); + const isBatchStopping = stoppingBatchSessionIds.includes(session.id); const hasUnreadTabs = session.aiTabs?.some(tab => tab.hasUnread); - // Sessions in Auto Run mode should show yellow/warning color + // Sessions in Auto Run mode should show yellow/warning color, red if stopping const effectiveStatusColor = isInBatch - ? theme.colors.warning + ? (isBatchStopping ? theme.colors.error : theme.colors.warning) : (session.toolType === 'claude' && !session.agentSessionId ? undefined // Will use border style instead : getStatusColor(session.state, theme)); - const shouldPulse = session.state === 'busy' || isInBatch; + // Don't pulse when stopping + const shouldPulse = (session.state === 'busy' || isInBatch) && !isBatchStopping; return (
g.id === session.groupId)?.name} + isInBatch={isInBatch} + isBatchStopping={isBatchStopping} />
diff --git a/src/renderer/components/ThinkingStatusPill.tsx b/src/renderer/components/ThinkingStatusPill.tsx index e34e5712..a0e7bbc0 100644 --- a/src/renderer/components/ThinkingStatusPill.tsx +++ b/src/renderer/components/ThinkingStatusPill.tsx @@ -237,14 +237,15 @@ const AutoRunPill = memo(({ style={{ backgroundColor: theme.colors.border }} />