diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/export-controls/export-controls.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/export-controls/export-controls.tsx
new file mode 100644
index 000000000..e116cb4a1
--- /dev/null
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/export-controls/export-controls.tsx
@@ -0,0 +1,165 @@
+'use client'
+
+import { useState } from 'react'
+import { Download, FileText } from 'lucide-react'
+import { Button } from '@/components/ui/button'
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu'
+import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
+import { createLogger } from '@/lib/logs/console-logger'
+import { useWorkflowStore } from '@/stores/workflows/workflow/store'
+import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
+import { useWorkflowYamlStore } from '@/stores/workflows/yaml/store'
+
+const logger = createLogger('ExportControls')
+
+interface ExportControlsProps {
+ disabled?: boolean
+}
+
+export function ExportControls({ disabled = false }: ExportControlsProps) {
+ const [isExporting, setIsExporting] = useState(false)
+ const workflowState = useWorkflowStore()
+ const { workflows, activeWorkflowId } = useWorkflowRegistry()
+ const getYaml = useWorkflowYamlStore(state => state.getYaml)
+
+ const currentWorkflow = activeWorkflowId ? workflows[activeWorkflowId] : null
+
+ const downloadFile = (content: string, filename: string, mimeType: string) => {
+ try {
+ const blob = new Blob([content], { type: mimeType })
+ const url = URL.createObjectURL(blob)
+ const a = document.createElement('a')
+ a.href = url
+ a.download = filename
+ document.body.appendChild(a)
+ a.click()
+ document.body.removeChild(a)
+ URL.revokeObjectURL(url)
+ } catch (error) {
+ logger.error('Failed to download file:', error)
+ }
+ }
+
+ const handleExportJson = async () => {
+ if (!currentWorkflow || !activeWorkflowId) {
+ logger.warn('No active workflow to export')
+ return
+ }
+
+ setIsExporting(true)
+ try {
+ const exportData = {
+ workflow: {
+ id: activeWorkflowId,
+ name: currentWorkflow.name,
+ description: currentWorkflow.description,
+ color: currentWorkflow.color,
+ },
+ state: {
+ blocks: workflowState.blocks,
+ edges: workflowState.edges,
+ loops: workflowState.loops,
+ parallels: workflowState.parallels,
+ },
+ exportedAt: new Date().toISOString(),
+ version: '1.0'
+ }
+
+ const jsonContent = JSON.stringify(exportData, null, 2)
+ const filename = `${currentWorkflow.name.replace(/[^a-z0-9]/gi, '_')}_workflow.json`
+
+ downloadFile(jsonContent, filename, 'application/json')
+ logger.info('Workflow exported as JSON')
+ } catch (error) {
+ logger.error('Failed to export workflow as JSON:', error)
+ } finally {
+ setIsExporting(false)
+ }
+ }
+
+ const handleExportYaml = async () => {
+ if (!currentWorkflow || !activeWorkflowId) {
+ logger.warn('No active workflow to export')
+ return
+ }
+
+ setIsExporting(true)
+ try {
+ const yamlContent = getYaml()
+ const filename = `${currentWorkflow.name.replace(/[^a-z0-9]/gi, '_')}_workflow.yaml`
+
+ downloadFile(yamlContent, filename, 'text/yaml')
+ logger.info('Workflow exported as YAML')
+ } catch (error) {
+ logger.error('Failed to export workflow as YAML:', error)
+ } finally {
+ setIsExporting(false)
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+
+ {disabled
+ ? 'Export not available'
+ : !currentWorkflow
+ ? 'No workflow to export'
+ : 'Export Workflow'
+ }
+
+
+
+
+
+
+
+ Export as JSON
+
+ Full workflow data
+
+
+
+
+
+
+
+
+
+ Export as YAML
+
+ Condensed workflow language
+
+
+
+
+
+ )
+}
\ No newline at end of file
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 855f41d30..a149be00f 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
@@ -56,6 +56,7 @@ import {
} from '../../../hooks/use-keyboard-shortcuts'
import { useWorkflowExecution } from '../../hooks/use-workflow-execution'
import { DeploymentControls } from './components/deployment-controls/deployment-controls'
+import { ExportControls } from './components/export-controls/export-controls'
import { HistoryDropdownItem } from './components/history-dropdown-item/history-dropdown-item'
import { MarketplaceModal } from './components/marketplace-modal/marketplace-modal'
import { NotificationDropdownItem } from './components/notification-dropdown-item/notification-dropdown-item'
@@ -1287,6 +1288,7 @@ export function ControlBar({ hasValidationErrors = false }: ControlBarProps) {
{renderDuplicateButton()}
{renderAutoLayoutButton()}
{renderDebugModeToggle()}
+
{/* {renderPublishButton()} */}
{renderDeployButton()}
{renderRunButton()}
diff --git a/apps/sim/package.json b/apps/sim/package.json
index 7d112d7ac..7c00c8e4a 100644
--- a/apps/sim/package.json
+++ b/apps/sim/package.json
@@ -65,6 +65,7 @@
"@radix-ui/react-tooltip": "^1.1.6",
"@react-email/components": "^0.0.34",
"@sentry/nextjs": "^9.15.0",
+ "@types/js-yaml": "4.0.9",
"@types/three": "0.177.0",
"@vercel/og": "^0.6.5",
"@vercel/speed-insights": "^1.2.0",
@@ -86,6 +87,7 @@
"input-otp": "^1.4.2",
"ioredis": "^5.6.0",
"jose": "6.0.11",
+ "js-yaml": "4.1.0",
"jwt-decode": "^4.0.0",
"lenis": "^1.2.3",
"lucide-react": "^0.479.0",
diff --git a/apps/sim/stores/workflows/yaml/README.md b/apps/sim/stores/workflows/yaml/README.md
new file mode 100644
index 000000000..b7c111976
--- /dev/null
+++ b/apps/sim/stores/workflows/yaml/README.md
@@ -0,0 +1,143 @@
+# Workflow YAML Store
+
+This store dynamically generates a condensed YAML representation of workflows from the JSON workflow state. It extracts input values, connections, and block relationships to create a clean, readable format.
+
+## Features
+
+- **Dynamic Input Extraction**: Automatically reads input values from block configurations and subblock stores
+- **Connection Mapping**: Determines preceding and following blocks from workflow edges
+- **Type-Aware Processing**: Handles different input types (text, numbers, booleans, objects) appropriately
+- **Auto-Refresh**: Automatically updates when workflow state or input values change
+- **Clean Format**: Generates well-formatted YAML with proper indentation
+
+## YAML Structure
+
+```yaml
+version: "1.0"
+blocks:
+ block-id-1:
+ type: "starter"
+ name: "Start"
+ inputs:
+ startWorkflow: "manual"
+ following:
+ - "block-id-2"
+
+ block-id-2:
+ type: "agent"
+ name: "AI Agent"
+ inputs:
+ systemPrompt: "You are a helpful assistant"
+ userPrompt: "Process the input data"
+ model: "gpt-4"
+ temperature: 0.7
+ preceding:
+ - "block-id-1"
+ following:
+ - "block-id-3"
+```
+
+## Usage
+
+### Basic Usage
+
+```typescript
+import { useWorkflowYamlStore } from '@/stores/workflows/yaml/store'
+
+function WorkflowYamlViewer() {
+ const yaml = useWorkflowYamlStore(state => state.getYaml())
+
+ return (
+
+ {yaml}
+
+ )
+}
+```
+
+### Manual Refresh
+
+```typescript
+import { useWorkflowYamlStore } from '@/stores/workflows/yaml/store'
+
+function WorkflowControls() {
+ const refreshYaml = useWorkflowYamlStore(state => state.refreshYaml)
+
+ return (
+
+ )
+}
+```
+
+### Advanced Usage
+
+```typescript
+import { useWorkflowYamlStore } from '@/stores/workflows/yaml/store'
+
+function WorkflowExporter() {
+ const { yaml, lastGenerated, generateYaml } = useWorkflowYamlStore()
+
+ const exportToFile = () => {
+ const blob = new Blob([yaml], { type: 'text/yaml' })
+ const url = URL.createObjectURL(blob)
+ const a = document.createElement('a')
+ a.href = url
+ a.download = 'workflow.yaml'
+ a.click()
+ URL.revokeObjectURL(url)
+ }
+
+ return (
+
+
Last generated: {lastGenerated ? new Date(lastGenerated).toLocaleString() : 'Never'}
+
+
+
+ )
+}
+```
+
+## Input Types Handled
+
+The store intelligently processes different subblock input types:
+
+- **Text Inputs** (`short-input`, `long-input`): Trimmed strings
+- **Dropdowns/Combobox** (`dropdown`, `combobox`): Selected values
+- **Tables** (`table`): Arrays of objects (only if non-empty)
+- **Code Blocks** (`code`): Preserves formatting for strings and objects
+- **Switches** (`switch`): Boolean values
+- **Sliders** (`slider`): Numeric values
+- **Checkbox Lists** (`checkbox-list`): Arrays of selected items
+
+## Auto-Refresh Behavior
+
+The store automatically refreshes in these scenarios:
+
+1. **Workflow Structure Changes**: When blocks are added, removed, or connections change
+2. **Input Value Changes**: When any subblock input values are modified
+3. **Debounced Updates**: Changes are debounced to prevent excessive regeneration
+
+## Performance
+
+- **Lazy Generation**: YAML is only generated when requested
+- **Caching**: Results are cached and only regenerated when data changes
+- **Debouncing**: Rapid changes are debounced to improve performance
+- **Selective Updates**: Only regenerates when meaningful changes occur
+
+## Error Handling
+
+If YAML generation fails, the store returns an error message in YAML comment format:
+
+```yaml
+# Error generating YAML: [error message]
+```
+
+## Dependencies
+
+- `js-yaml`: For YAML serialization
+- `zustand`: For state management
+- `@/blocks`: For block configuration access
+- `@/stores/workflows/workflow/store`: For workflow state
+- `@/stores/workflows/subblock/store`: For input values
\ No newline at end of file
diff --git a/apps/sim/stores/workflows/yaml/store.ts b/apps/sim/stores/workflows/yaml/store.ts
new file mode 100644
index 000000000..37f17fe89
--- /dev/null
+++ b/apps/sim/stores/workflows/yaml/store.ts
@@ -0,0 +1,268 @@
+import { create } from 'zustand'
+import { devtools } from 'zustand/middleware'
+import { dump as yamlDump } from 'js-yaml'
+import { getBlock } from '@/blocks'
+import { createLogger } from '@/lib/logs/console-logger'
+import { useWorkflowStore } from '../workflow/store'
+import { useSubBlockStore } from '../subblock/store'
+import type { BlockState, WorkflowState } from '../workflow/types'
+import type { SubBlockConfig } from '@/blocks/types'
+
+const logger = createLogger('WorkflowYamlStore')
+
+interface YamlBlock {
+ type: string
+ name: string
+ inputs?: Record
+ preceding?: string[]
+ following?: string[]
+}
+
+interface YamlWorkflow {
+ version: string
+ blocks: Record
+}
+
+interface WorkflowYamlState {
+ yaml: string
+ lastGenerated?: number
+}
+
+interface WorkflowYamlActions {
+ generateYaml: () => void
+ getYaml: () => string
+ refreshYaml: () => void
+}
+
+type WorkflowYamlStore = WorkflowYamlState & WorkflowYamlActions
+
+/**
+ * Extract input values from a block's subBlocks based on its configuration
+ */
+function extractBlockInputs(blockState: BlockState, blockId: string): Record {
+ const blockConfig = getBlock(blockState.type)
+ const subBlockStore = useSubBlockStore.getState()
+ const inputs: Record = {}
+
+ if (!blockConfig) {
+ // For custom blocks like loops/parallels, extract available subBlock values
+ Object.entries(blockState.subBlocks || {}).forEach(([subBlockId, subBlockState]) => {
+ const value = subBlockStore.getValue(blockId, subBlockId) ?? subBlockState.value
+ if (value !== undefined && value !== null && value !== '') {
+ inputs[subBlockId] = value
+ }
+ })
+ return inputs
+ }
+
+ // Process each subBlock configuration
+ blockConfig.subBlocks.forEach((subBlockConfig: SubBlockConfig) => {
+ const subBlockId = subBlockConfig.id
+
+ // Skip hidden or conditional fields that aren't active
+ if (subBlockConfig.hidden) return
+
+ // Get value from subblock store or fallback to block state
+ const value = subBlockStore.getValue(blockId, subBlockId) ??
+ blockState.subBlocks[subBlockId]?.value
+
+ // Include value if it exists and isn't empty
+ if (value !== undefined && value !== null && value !== '') {
+ // Handle different input types appropriately
+ switch (subBlockConfig.type) {
+ case 'table':
+ // Tables are arrays of objects
+ if (Array.isArray(value) && value.length > 0) {
+ inputs[subBlockId] = value
+ }
+ break
+
+ case 'checkbox-list':
+ // Checkbox lists return arrays
+ if (Array.isArray(value) && value.length > 0) {
+ inputs[subBlockId] = value
+ }
+ break
+
+ case 'code':
+ // Code blocks should preserve formatting
+ if (typeof value === 'string' && value.trim()) {
+ inputs[subBlockId] = value
+ } else if (typeof value === 'object') {
+ inputs[subBlockId] = value
+ }
+ break
+
+ case 'switch':
+ // Boolean values
+ inputs[subBlockId] = Boolean(value)
+ break
+
+ case 'slider':
+ // Numeric values
+ if (typeof value === 'number' || (typeof value === 'string' && !isNaN(Number(value)))) {
+ inputs[subBlockId] = Number(value)
+ }
+ break
+
+ default:
+ // Text inputs, dropdowns, etc.
+ if (typeof value === 'string' && value.trim()) {
+ inputs[subBlockId] = value.trim()
+ } else if (typeof value === 'object' || typeof value === 'number' || typeof value === 'boolean') {
+ inputs[subBlockId] = value
+ }
+ break
+ }
+ }
+ })
+
+ return inputs
+}
+
+/**
+ * Find preceding blocks for a given block ID
+ */
+function findPrecedingBlocks(blockId: string, edges: any[]): string[] {
+ return edges
+ .filter(edge => edge.target === blockId)
+ .map(edge => edge.source)
+ .filter((source, index, arr) => arr.indexOf(source) === index) // Remove duplicates
+}
+
+/**
+ * Find following blocks for a given block ID
+ */
+function findFollowingBlocks(blockId: string, edges: any[]): string[] {
+ return edges
+ .filter(edge => edge.source === blockId)
+ .map(edge => edge.target)
+ .filter((target, index, arr) => arr.indexOf(target) === index) // Remove duplicates
+}
+
+/**
+ * Generate YAML representation of the workflow
+ */
+function generateWorkflowYaml(workflowState: WorkflowState): string {
+ try {
+ const yamlWorkflow: YamlWorkflow = {
+ version: '1.0',
+ blocks: {}
+ }
+
+ // Process each block
+ Object.entries(workflowState.blocks).forEach(([blockId, blockState]) => {
+ const inputs = extractBlockInputs(blockState, blockId)
+ const preceding = findPrecedingBlocks(blockId, workflowState.edges)
+ const following = findFollowingBlocks(blockId, workflowState.edges)
+
+ const yamlBlock: YamlBlock = {
+ type: blockState.type,
+ name: blockState.name
+ }
+
+ // Only include inputs if they exist
+ if (Object.keys(inputs).length > 0) {
+ yamlBlock.inputs = inputs
+ }
+
+ // Only include connections if they exist
+ if (preceding.length > 0) {
+ yamlBlock.preceding = preceding
+ }
+
+ if (following.length > 0) {
+ yamlBlock.following = following
+ }
+
+ yamlWorkflow.blocks[blockId] = yamlBlock
+ })
+
+ // Convert to YAML with clean formatting
+ return yamlDump(yamlWorkflow, {
+ indent: 2,
+ lineWidth: -1, // Disable line wrapping
+ noRefs: true,
+ sortKeys: false
+ })
+ } catch (error) {
+ logger.error('Failed to generate workflow YAML:', error)
+ return `# Error generating YAML: ${error instanceof Error ? error.message : 'Unknown error'}`
+ }
+}
+
+export const useWorkflowYamlStore = create()(
+ devtools(
+ (set, get) => ({
+ yaml: '',
+ lastGenerated: undefined,
+
+ generateYaml: () => {
+ const workflowState = useWorkflowStore.getState()
+ const yaml = generateWorkflowYaml(workflowState)
+
+ set({
+ yaml,
+ lastGenerated: Date.now()
+ })
+ },
+
+ getYaml: () => {
+ const currentTime = Date.now()
+ const { yaml, lastGenerated } = get()
+
+ // Auto-refresh if data is stale (older than 1 second) or never generated
+ if (!lastGenerated || currentTime - lastGenerated > 1000) {
+ get().generateYaml()
+ return get().yaml
+ }
+
+ return yaml
+ },
+
+ refreshYaml: () => {
+ get().generateYaml()
+ }
+ }),
+ {
+ name: 'workflow-yaml-store'
+ }
+ )
+)
+
+// Auto-refresh YAML when workflow state changes
+let lastWorkflowState: { blockCount: number; edgeCount: number } | null = null
+
+useWorkflowStore.subscribe((state) => {
+ const currentState = {
+ blockCount: Object.keys(state.blocks).length,
+ edgeCount: state.edges.length
+ }
+
+ // Only refresh if the structure has changed
+ if (!lastWorkflowState ||
+ lastWorkflowState.blockCount !== currentState.blockCount ||
+ lastWorkflowState.edgeCount !== currentState.edgeCount) {
+
+ lastWorkflowState = currentState
+
+ // Debounce the refresh to avoid excessive updates
+ const refreshYaml = useWorkflowYamlStore.getState().refreshYaml
+ setTimeout(refreshYaml, 100)
+ }
+})
+
+// Subscribe to subblock store changes
+let lastSubBlockChangeTime = 0
+
+useSubBlockStore.subscribe((state) => {
+ const currentTime = Date.now()
+
+ // Debounce rapid changes
+ if (currentTime - lastSubBlockChangeTime > 100) {
+ lastSubBlockChangeTime = currentTime
+
+ const refreshYaml = useWorkflowYamlStore.getState().refreshYaml
+ setTimeout(refreshYaml, 100)
+ }
+})
\ No newline at end of file
diff --git a/bun.lock b/bun.lock
index 01d0336af..8e086568b 100644
--- a/bun.lock
+++ b/bun.lock
@@ -95,6 +95,7 @@
"@radix-ui/react-tooltip": "^1.1.6",
"@react-email/components": "^0.0.34",
"@sentry/nextjs": "^9.15.0",
+ "@types/js-yaml": "4.0.9",
"@types/three": "0.177.0",
"@vercel/og": "^0.6.5",
"@vercel/speed-insights": "^1.2.0",
@@ -116,6 +117,7 @@
"input-otp": "^1.4.2",
"ioredis": "^5.6.0",
"jose": "6.0.11",
+ "js-yaml": "4.1.0",
"jwt-decode": "^4.0.0",
"lenis": "^1.2.3",
"lucide-react": "^0.479.0",
@@ -1324,6 +1326,8 @@
"@types/jest": ["@types/jest@26.0.24", "", { "dependencies": { "jest-diff": "^26.0.0", "pretty-format": "^26.0.0" } }, "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w=="],
+ "@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="],
+
"@types/jsdom": ["@types/jsdom@21.1.7", "", { "dependencies": { "@types/node": "*", "@types/tough-cookie": "*", "parse5": "^7.0.0" } }, "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA=="],
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
@@ -1482,7 +1486,7 @@
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
- "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
+ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
@@ -3472,8 +3476,6 @@
"jest-diff/pretty-format": ["pretty-format@26.6.2", "", { "dependencies": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^17.0.1" } }, "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg=="],
- "js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
-
"jsondiffpatch/chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
"linebreak/base64-js": ["base64-js@0.0.8", "", {}, "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw=="],
@@ -3498,6 +3500,8 @@
"loose-envify/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
+ "mammoth/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
+
"mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
@@ -3844,6 +3848,8 @@
"openai/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
+ "openapi/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
+
"openapi/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
"ora/cli-cursor/restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],