diff --git a/sim/app/w/[id]/components/control-bar/control-bar.tsx b/sim/app/w/[id]/components/control-bar/control-bar.tsx
index 72c785b490..7fcfa2843e 100644
--- a/sim/app/w/[id]/components/control-bar/control-bar.tsx
+++ b/sim/app/w/[id]/components/control-bar/control-bar.tsx
@@ -44,6 +44,7 @@ import { useGeneralStore } from '@/stores/settings/general/store'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
+import { getKeyboardShortcutText, useKeyboardShortcuts } from '../../hooks/use-keyboard-shortcuts'
import { useWorkflowExecution } from '../../hooks/use-workflow-execution'
import { DeploymentControls } from './components/deployment-controls/deployment-controls'
import { HistoryDropdownItem } from './components/history-dropdown-item/history-dropdown-item'
@@ -108,6 +109,20 @@ export function ControlBar() {
const [isCancelling, setIsCancelling] = useState(false)
const cancelFlagRef = useRef(false)
+ // Register keyboard shortcut for running workflow
+ useKeyboardShortcuts(
+ () => {
+ if (!isExecuting && !isMultiRunning && !isCancelling) {
+ if (isDebugModeEnabled) {
+ handleRunWorkflow()
+ } else {
+ handleMultipleRuns()
+ }
+ }
+ },
+ isExecuting || isMultiRunning || isCancelling
+ )
+
// Get notifications for current workflow
const workflowNotifications = activeWorkflowId
? getWorkflowNotifications(activeWorkflowId)
@@ -820,44 +835,58 @@ export function ControlBar() {
{/* Main Run/Debug Button */}
-
+
+
+
+
+
+ {isDebugModeEnabled
+ ? 'Debug Workflow'
+ : runCount === 1
+ ? 'Run Workflow'
+ : `Run Workflow ${runCount} times`}
+
+ {getKeyboardShortcutText('Enter', true)}
+
+
+
{/* Dropdown Trigger - Only show when not in debug mode and not multi-running */}
{!isDebugModeEnabled && !isMultiRunning && (
diff --git a/sim/app/w/[id]/hooks/use-keyboard-shortcuts.ts b/sim/app/w/[id]/hooks/use-keyboard-shortcuts.ts
new file mode 100644
index 0000000000..cbdcb5b51a
--- /dev/null
+++ b/sim/app/w/[id]/hooks/use-keyboard-shortcuts.ts
@@ -0,0 +1,70 @@
+'use client'
+
+import { useEffect, useMemo } from 'react'
+
+/**
+ * Detect if the current platform is Mac
+ */
+export function isMacPlatform() {
+ if (typeof navigator === 'undefined') return false
+ return navigator.platform.toUpperCase().indexOf('MAC') >= 0
+}
+
+/**
+ * Get a formatted keyboard shortcut string for display
+ * @param key The key part of the shortcut (e.g., "Enter")
+ * @param requiresCmd Whether the shortcut requires Cmd/Ctrl
+ * @param requiresShift Whether the shortcut requires Shift
+ * @param requiresAlt Whether the shortcut requires Alt/Option
+ */
+export function getKeyboardShortcutText(
+ key: string,
+ requiresCmd = false,
+ requiresShift = false,
+ requiresAlt = false
+) {
+ const isMac = isMacPlatform()
+ const cmdKey = isMac ? '⌘' : 'Ctrl'
+ const altKey = isMac ? '⌥' : 'Alt'
+ const shiftKey = '⇧'
+
+ const parts: string[] = []
+ if (requiresCmd) parts.push(cmdKey)
+ if (requiresShift) parts.push(shiftKey)
+ if (requiresAlt) parts.push(altKey)
+ parts.push(key)
+
+ return parts.join('+')
+}
+
+/**
+ * Hook to manage keyboard shortcuts
+ * @param onRunWorkflow - Function to run when Cmd/Ctrl+Enter is pressed
+ * @param isDisabled - Whether shortcuts should be disabled
+ */
+export function useKeyboardShortcuts(onRunWorkflow: () => void, isDisabled = false) {
+ // Memoize the platform detection
+ const isMac = useMemo(() => isMacPlatform(), [])
+
+ useEffect(() => {
+ const handleKeyDown = (event: KeyboardEvent) => {
+ // Run workflow with Cmd+Enter (Mac) or Ctrl+Enter (Windows/Linux)
+ if (event.key === 'Enter' && ((isMac && event.metaKey) || (!isMac && event.ctrlKey))) {
+ // Don't trigger if user is typing in an input, textarea, or contenteditable element
+ const activeElement = document.activeElement
+ const isEditableElement =
+ activeElement instanceof HTMLInputElement ||
+ activeElement instanceof HTMLTextAreaElement ||
+ activeElement?.hasAttribute('contenteditable')
+
+ if (!isEditableElement && !isDisabled) {
+ event.preventDefault()
+ onRunWorkflow()
+ }
+ }
+ }
+
+ window.addEventListener('keydown', handleKeyDown)
+ return () => window.removeEventListener('keydown', handleKeyDown)
+ }, [onRunWorkflow, isDisabled, isMac])
+}
\ No newline at end of file