-
-
- {stateDisplay.label}
-
+ {/* Executor state badge and engine controls */}
+
+ engineControlMenuRef.current?.open()}
+ aria-label={t("executor.openEngineControlsForState", "Open engine controls for {{state}} state", { state: stateDisplay.label })}
+ data-testid="executor-state-engine-control-trigger"
+ >
+
+
+ {stateDisplay.label}
+
+
+
);
diff --git a/packages/dashboard/app/components/Header.css b/packages/dashboard/app/components/Header.css
index 8b3ee01089..8a2e43c497 100644
--- a/packages/dashboard/app/components/Header.css
+++ b/packages/dashboard/app/components/Header.css
@@ -387,90 +387,6 @@ non-notched devices, so this is a no-op there. Pair with viewport-fit=cover (ind
flex-shrink: 0;
}
-/* Split-button for engine controls */
-.engine-control-split-btn {
- position: relative;
- display: flex;
- align-items: center;
- border-radius: var(--radius-md);
-}
-
-.engine-control-split-btn__main {
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
-}
-
-.engine-control-split-btn__chevron {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
- min-width: 28px;
- padding: 0;
-}
-
-.engine-control-split-btn__divider {
- width: 1px;
- height: 16px;
- background: var(--border);
- flex-shrink: 0;
-}
-
-.engine-control-split-btn__menu {
- position: absolute;
- top: calc(100% + 4px);
- right: 0;
- min-width: 160px;
- background: var(--card);
- border: 1px solid var(--border);
- border-radius: var(--radius-md);
- box-shadow: var(--shadow-md);
- z-index: 200;
- overflow: hidden;
-}
-
-.engine-control-split-btn__menu-item {
- display: flex;
- align-items: center;
- gap: var(--space-sm);
- width: 100%;
- padding: var(--space-xs) var(--space-sm);
- background: none;
- border: none;
- color: var(--text-muted);
- font-size: 13px;
- cursor: pointer;
- text-align: left;
- transition: background var(--transition-fast), color var(--transition-fast);
-}
-
-.engine-control-split-btn__menu-item:disabled {
- opacity: 0.4;
- cursor: not-allowed;
-}
-
-.engine-control-split-btn__menu-item:focus-visible {
- background: var(--card-hover);
- box-shadow: var(--focus-ring-strong);
- color: var(--text);
- outline: none;
-}
-
-@media (hover: hover) {
- .engine-control-split-btn__menu-item:not(:disabled):hover {
- background: var(--card-hover);
- color: var(--text);
- }
-}
-
-.engine-control-split-btn__menu-item--active {
- color: var(--triage);
-}
-
-@media (hover: hover) {
- .engine-control-split-btn__menu-item--active:not(:disabled):hover {
- color: var(--triage);
- }
-}
-
/* Header badge for active sessions */
.btn-icon--has-indicator {
position: relative;
@@ -1023,11 +939,6 @@ non-notched devices, so this is a no-op there. Pair with viewport-fit=cover (ind
min-height: 36px;
}
- .engine-control-split-btn__main,
- .engine-control-split-btn__chevron {
- min-width: 36px;
- min-height: 36px;
- }
/* Mobile header: collapsible search trigger */
.mobile-search-trigger {
diff --git a/packages/dashboard/app/components/Header.tsx b/packages/dashboard/app/components/Header.tsx
index 8d1f9ae752..0ab935b712 100644
--- a/packages/dashboard/app/components/Header.tsx
+++ b/packages/dashboard/app/components/Header.tsx
@@ -1,6 +1,6 @@
import { useState, useEffect, useRef, useCallback, useMemo, type KeyboardEvent as ReactKeyboardEvent, type ReactNode } from "react";
import { useTranslation } from "react-i18next";
-import { Settings, Pause, Play, Square, LayoutGrid, List, Terminal, Lightbulb, Search, X, Activity, MoreHorizontal, Clock, Folder, History, GitBranch, Monitor, Workflow, Bot, Target, ChevronRight, FileCode, Loader2, Grid3X3, Mail, MessageSquare, ChevronDown, Check, Zap, Sparkles, FileText, Brain, CheckSquare, Lock, Gauge } from "lucide-react";
+import { Settings, Play, LayoutGrid, List, Terminal, Lightbulb, Search, X, Activity, MoreHorizontal, Clock, Folder, History, GitBranch, Monitor, Workflow, Bot, Target, ChevronRight, FileCode, Loader2, Grid3X3, Mail, MessageSquare, ChevronDown, Check, Zap, Sparkles, FileText, Brain, CheckSquare, Lock, Gauge } from "lucide-react";
import "./Header.css";
// ProjectSelector styles used by the imported standalone component.
import "./ProjectSelector.css";
@@ -87,10 +87,6 @@ export interface HeaderProps {
onOpenTodos?: () => void;
todosOpen?: boolean;
todosEnabled?: boolean;
- globalPaused?: boolean;
- enginePaused?: boolean;
- onToggleGlobalPause?: () => void;
- onToggleEnginePause?: () => void;
view?: TaskView;
onChangeView?: (view: TaskView) => void;
/** Whether to show the skills tab in the view toggle */
@@ -154,10 +150,6 @@ export function Header({
onOpenTodos,
todosOpen,
todosEnabled,
- globalPaused,
- enginePaused,
- onToggleGlobalPause,
- onToggleEnginePause,
view = "board",
onChangeView,
showSkillsTab,
@@ -210,7 +202,6 @@ export function Header({
const [isMobileProjectSwitchOpen, setIsMobileProjectSwitchOpen] = useState(false);
const [isViewOverflowOpen, setIsViewOverflowOpen] = useState(false);
const [isDesktopOverflowOpen, setIsDesktopOverflowOpen] = useState(false);
- const [isEngineMenuOpen, setIsEngineMenuOpen] = useState(false);
const [isScriptsOpen, setIsScriptsOpen] = useState(false);
const [scripts, setScripts] = useState