From 7c73f5ffe0aebf94e3dcbcd8ff180bbcfc239bd7 Mon Sep 17 00:00:00 2001
From: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
Date: Thu, 28 Aug 2025 18:19:20 -0700
Subject: [PATCH] feat(debug): create debugger (#1174)
* Updates
* Updates
* Updates
* Checkpoint
* Checkpoint
* Checkpoitn
* Var improvements
* Fixes
* Execution status
* UI improvements
* Ui updates
* Fix
* Fix scoping
* Fix workflow vars
* Fix env vars
* Remove number styling
* Variable highlighting
* Updates
* Update
* Fix resume
* Stuff
* Breakpoint ui
* Ui
* Ui updates
* Loops and parallels
* HIde env vars
* Checkpoint
* Stuff
* Panel toggle
* Lint
---
.../components/control-bar/control-bar.tsx | 75 +-
.../panel/components/debug/debug.tsx | 2093 +++++++++++++++++
.../w/[workflowId]/components/panel/panel.tsx | 46 +-
.../workflow-block/workflow-block.tsx | 110 +-
.../hooks/use-workflow-execution.ts | 53 +-
apps/sim/executor/index.ts | 2 +-
apps/sim/stores/execution/store.ts | 3 +
apps/sim/stores/execution/types.ts | 9 +
apps/sim/stores/panel/types.ts | 2 +-
9 files changed, 2322 insertions(+), 71 deletions(-)
create mode 100644 apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/debug/debug.tsx
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.tsx
index b453c54139..4954a6702c 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/control-bar.tsx
@@ -8,8 +8,6 @@ import {
Layers,
Play,
RefreshCw,
- SkipForward,
- StepForward,
Store,
Trash2,
WifiOff,
@@ -44,6 +42,7 @@ import {
getKeyboardShortcutText,
useKeyboardShortcuts,
} from '@/app/workspace/[workspaceId]/w/hooks/use-keyboard-shortcuts'
+import { useExecutionStore } from '@/stores/execution/store'
import { useFolderStore } from '@/stores/folders/store'
import { usePanelStore } from '@/stores/panel/store'
import { useGeneralStore } from '@/stores/settings/general/store'
@@ -111,6 +110,9 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
const [isExpanded, setIsExpanded] = useState(false)
const [isTemplateModalOpen, setIsTemplateModalOpen] = useState(false)
const [isAutoLayouting, setIsAutoLayouting] = useState(false)
+ // Remove chat modal state
+ // const [isChatPromptOpen, setIsChatPromptOpen] = useState(false)
+ // const [chatPrompt, setChatPrompt] = useState('')
// Delete workflow state - grouped for better organization
const [deleteState, setDeleteState] = useState({
@@ -146,6 +148,13 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
}
}, [setActiveTab, isOpen, togglePanel])
+ const openDebugPanel = useCallback(() => {
+ setActiveTab('debug')
+ if (!isOpen) {
+ togglePanel()
+ }
+ }, [setActiveTab, isOpen, togglePanel])
+
// Shared condition for keyboard shortcut and button disabled state
const isWorkflowBlocked = isExecuting || hasValidationErrors
@@ -819,15 +828,29 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
return // Do nothing if no executable blocks
}
- // Start debugging
+ // Determine starter id for focus
+ const starter = Object.values(blocks).find((b) => b.type === 'starter') as any
+ const starterId = starter?.id as string | undefined
+
+ // Enable debug UI but do NOT start execution
if (!isDebugModeEnabled) {
toggleDebugMode()
}
if (usageExceeded) {
openSubscriptionSettings()
} else {
- openConsolePanel()
- handleRunWorkflow(undefined, true) // Start in debug mode
+ // Activate debug session state so the panel is active
+ const execStore = useExecutionStore.getState()
+ execStore.setIsExecuting(false)
+ execStore.setIsDebugging(true)
+ // Set the Start block as pending - it will execute on first Step
+ execStore.setPendingBlocks(starterId ? [starterId] : [])
+
+ // Show Debug tab and mark starter as the current block to execute
+ openDebugPanel()
+ if (starterId) {
+ execStore.setActiveBlocks(new Set([starterId]))
+ }
}
}
}, [
@@ -838,8 +861,7 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
blocks,
handleCancelDebug,
toggleDebugMode,
- handleRunWorkflow,
- openConsolePanel,
+ openDebugPanel,
])
/**
@@ -859,40 +881,7 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
return (
-
-
-
-
- Step Forward
-
-
-
-
-
-
- Resume Until End
-
-
+ {/* Keep only cancel (X) here; step/resume moved to panel */}
)}
+
+ {/* Removed chat prompt dialog; chat input now lives in DebugPanel */}
)
}
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/debug/debug.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/debug/debug.tsx
new file mode 100644
index 0000000000..10a2213ef7
--- /dev/null
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/debug/debug.tsx
@@ -0,0 +1,2093 @@
+'use client'
+
+import { useEffect, useMemo, useRef, useState } from 'react'
+import {
+ AlertCircle,
+ Check,
+ Circle,
+ CircleDot,
+ FastForward,
+ Play,
+ RotateCcw,
+ Square,
+ X,
+} from 'lucide-react'
+import { Button } from '@/components/ui/button'
+import { Checkbox } from '@/components/ui/checkbox'
+import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
+import { Textarea } from '@/components/ui/textarea'
+import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
+import { BlockPathCalculator } from '@/lib/block-path-calculator'
+import { extractFieldsFromSchema, parseResponseFormatSafely } from '@/lib/response-format'
+import { cn } from '@/lib/utils'
+import { useCurrentWorkflow } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-current-workflow'
+import { useWorkflowExecution } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution'
+import { getBlock } from '@/blocks'
+import { useExecutionStore } from '@/stores/execution/store'
+import { useVariablesStore } from '@/stores/panel/variables/store'
+import { useEnvironmentStore } from '@/stores/settings/environment/store'
+import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
+import { useSubBlockStore } from '@/stores/workflows/subblock/store'
+import { mergeSubblockState } from '@/stores/workflows/utils'
+import { useWorkflowStore } from '@/stores/workflows/workflow/store'
+import { getTool } from '@/tools/utils'
+import { getTrigger, getTriggersByProvider } from '@/triggers'
+
+export function DebugPanel() {
+ const {
+ isDebugging,
+ pendingBlocks,
+ debugContext,
+ executor,
+ activeBlockIds,
+ setActiveBlocks,
+ setPanelFocusedBlockId,
+ panelFocusedBlockId,
+ setExecutingBlockIds,
+ setDebugContext,
+ setPendingBlocks,
+ breakpointId,
+ setBreakpointId,
+ } = useExecutionStore()
+ const { activeWorkflowId, workflows } = useWorkflowRegistry()
+ const { handleStepDebug, handleResumeDebug, handleCancelDebug, handleRunWorkflow } =
+ useWorkflowExecution()
+ const currentWorkflow = useCurrentWorkflow()
+
+ const [chatMessage, setChatMessage] = useState('')
+ const [scopedVariables, setScopedVariables] = useState(true)
+ const [expandedFields, setExpandedFields] = useState>(new Set())
+ const [revealedEnvVars, setRevealedEnvVars] = useState>(new Set())
+ const hasStartedRef = useRef(false)
+ const lastFocusedIdRef = useRef(null)
+
+ // Track bottom variables tab and row highlighting for navigation from tokens
+ const [bottomTab, setBottomTab] = useState<'reference' | 'workflow' | 'environment'>('reference')
+ const workflowVarRowRefs = useRef