@flowdrop/flowdrop 1.9.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/api/enhanced-client.js +5 -1
  2. package/dist/components/Navbar.svelte +1 -10
  3. package/dist/components/Navbar.svelte.d.ts +1 -9
  4. package/dist/components/PipelineStatus.svelte +17 -1
  5. package/dist/components/PipelineStatus.svelte.d.ts +2 -0
  6. package/dist/components/WorkflowEditor.svelte +26 -0
  7. package/dist/components/playground/ChatPanel.svelte +33 -235
  8. package/dist/components/playground/ExecutionList.svelte +2 -6
  9. package/dist/components/playground/MessageBubble.svelte +61 -4
  10. package/dist/components/playground/PipelinePanel.svelte +17 -7
  11. package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -1
  12. package/dist/components/playground/Playground.svelte +123 -73
  13. package/dist/components/playground/PlaygroundApp.svelte +110 -0
  14. package/dist/components/playground/PlaygroundApp.svelte.d.ts +28 -0
  15. package/dist/components/playground/PlaygroundStudio.svelte +404 -0
  16. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +30 -0
  17. package/dist/editor/index.d.ts +1 -1
  18. package/dist/editor/index.js +1 -1
  19. package/dist/playground/index.d.ts +8 -3
  20. package/dist/playground/index.js +15 -5
  21. package/dist/playground/mount.d.ts +63 -4
  22. package/dist/playground/mount.js +173 -84
  23. package/dist/services/nodeExecutionService.js +4 -2
  24. package/dist/services/playgroundService.d.ts +11 -4
  25. package/dist/services/playgroundService.js +22 -12
  26. package/dist/stores/playgroundStore.svelte.d.ts +22 -21
  27. package/dist/stores/playgroundStore.svelte.js +79 -58
  28. package/dist/svelte-app.d.ts +2 -10
  29. package/dist/types/navbar.d.ts +14 -0
  30. package/dist/types/navbar.js +1 -0
  31. package/dist/types/playground.d.ts +3 -5
  32. package/package.json +1 -1
@@ -0,0 +1,404 @@
1
+ <!--
2
+ PlaygroundStudio Component
3
+
4
+ Drop-in embeddable split-pane layout: PipelinePanel (left, resizable) + Playground
5
+ chat (right). Provides the same integrated experience as the FlowDrop demo app with a
6
+ single import and zero layout glue code.
7
+
8
+ @example Basic usage — workflow fetched automatically
9
+ ```svelte
10
+ <script>
11
+ import { PlaygroundStudio, createEndpointConfig } from '@flowdrop/flowdrop/playground';
12
+ import '@flowdrop/flowdrop/styles';
13
+ </script>
14
+
15
+ <PlaygroundStudio
16
+ workflowId="wf-123"
17
+ endpointConfig={createEndpointConfig('/api/flowdrop')}
18
+ />
19
+ ```
20
+
21
+ @example With pre-loaded workflow and URL-based session routing
22
+ ```svelte
23
+ <script>
24
+ import { PlaygroundStudio, createEndpointConfig } from '@flowdrop/flowdrop/playground';
25
+
26
+ let { data } = $props(); // workflow from server load
27
+ let sessionId = $derived($page.params.sessionId);
28
+
29
+ function handleSessionNavigate(id) {
30
+ goto(`/playground/${id}`);
31
+ }
32
+ </script>
33
+
34
+ <PlaygroundStudio
35
+ workflowId={data.workflow.id}
36
+ workflow={data.workflow}
37
+ endpointConfig={createEndpointConfig('/api/flowdrop')}
38
+ initialSessionId={sessionId}
39
+ onSessionNavigate={handleSessionNavigate}
40
+ />
41
+ ```
42
+ -->
43
+
44
+ <script lang="ts">
45
+ import { onMount } from 'svelte';
46
+ import Icon from '@iconify/svelte';
47
+ import Playground from './Playground.svelte';
48
+ import PipelinePanel from './PipelinePanel.svelte';
49
+ import { getPipelinePanelOpen, pipelinePanelActions } from '../../stores/pipelinePanelStore.svelte.js';
50
+ import {
51
+ getActiveExecutionId,
52
+ getPinnedExecutionId,
53
+ getLatestExecutionId,
54
+ getPipelineRefreshTrigger,
55
+ getCurrentSession,
56
+ playgroundActions,
57
+ } from '../../stores/playgroundStore.svelte.js';
58
+ import { setEndpointConfig, workflowApi } from '../../services/api.js';
59
+ import { logger } from '../../utils/logger.js';
60
+ import type { Workflow } from '../../types/index.js';
61
+ import type { EndpointConfig } from '../../config/endpoints.js';
62
+ import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
63
+
64
+ interface Props {
65
+ /** Target workflow ID */
66
+ workflowId: string;
67
+ /** Pre-loaded workflow — skips internal fetch when provided */
68
+ workflow?: Workflow;
69
+ /** API endpoint configuration */
70
+ endpointConfig?: EndpointConfig;
71
+ /** Display mode (default: standalone) */
72
+ mode?: PlaygroundMode;
73
+ /** Session ID to activate on mount. Changing this prop remounts the Playground. */
74
+ initialSessionId?: string;
75
+ /** Playground configuration options */
76
+ config?: PlaygroundConfig;
77
+ /** Whether the pipeline panel starts open. When omitted the stored preference is used. */
78
+ initialPipelineOpen?: boolean;
79
+ /** Minimum chat panel width in px (default: 760) */
80
+ minChatWidth?: number;
81
+ /** Initial pipeline panel width in px (default: 500) */
82
+ initialPipelineWidth?: number;
83
+ /** Called when session navigation is requested — use for URL-based routing */
84
+ onSessionNavigate?: (sessionId: string) => void;
85
+ /** Called when the playground is closed (embedded / modal mode) */
86
+ onClose?: () => void;
87
+ }
88
+
89
+ let {
90
+ workflowId,
91
+ workflow: workflowProp,
92
+ endpointConfig,
93
+ mode = 'standalone',
94
+ initialSessionId,
95
+ config = {},
96
+ initialPipelineOpen,
97
+ minChatWidth = 760,
98
+ initialPipelineWidth = 500,
99
+ onSessionNavigate,
100
+ onClose,
101
+ }: Props = $props();
102
+
103
+ // svelte-ignore state_referenced_locally
104
+ let resolvedWorkflow = $state<Workflow | null>(workflowProp ?? null);
105
+ // svelte-ignore state_referenced_locally
106
+ let workflowLoading = $state(workflowProp === undefined);
107
+ let workflowError = $state<string | null>(null);
108
+
109
+ let splitEl = $state<HTMLElement | null>(null);
110
+ // svelte-ignore state_referenced_locally
111
+ let pipelineWidth = $state(initialPipelineWidth);
112
+ let isResizing = $state(false);
113
+ let containerWidth = $state(0);
114
+
115
+ $effect(() => {
116
+ if (!splitEl) return;
117
+ const observer = new ResizeObserver(([entry]) => {
118
+ containerWidth = entry.contentRect.width;
119
+ });
120
+ observer.observe(splitEl);
121
+ return () => observer.disconnect();
122
+ });
123
+
124
+ onMount(() => {
125
+ pipelinePanelActions.init();
126
+ if (initialPipelineOpen !== undefined) {
127
+ pipelinePanelActions.setOpen(initialPipelineOpen);
128
+ }
129
+ if (endpointConfig) {
130
+ setEndpointConfig(endpointConfig);
131
+ }
132
+ if (!workflowProp) {
133
+ void loadWorkflow();
134
+ }
135
+ });
136
+
137
+ async function loadWorkflow(): Promise<void> {
138
+ if (!endpointConfig) {
139
+ workflowError = 'Provide a workflow prop or an endpointConfig so the workflow can be fetched.';
140
+ workflowLoading = false;
141
+ return;
142
+ }
143
+
144
+ try {
145
+ workflowLoading = true;
146
+ workflowError = null;
147
+ resolvedWorkflow = await workflowApi.getWorkflow(workflowId);
148
+ } catch (err) {
149
+ workflowError = err instanceof Error ? err.message : 'Failed to load workflow';
150
+ logger.error('[PlaygroundStudio] Workflow load failed:', err);
151
+ } finally {
152
+ workflowLoading = false;
153
+ }
154
+ }
155
+
156
+ function handleResizerPointerDown(e: PointerEvent) {
157
+ isResizing = true;
158
+ (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
159
+ }
160
+
161
+ function handleResizerPointerMove(e: PointerEvent) {
162
+ if (!isResizing || !splitEl) return;
163
+ const rect = splitEl.getBoundingClientRect();
164
+ pipelineWidth = Math.min(
165
+ Math.max(e.clientX - rect.left, rect.width - minChatWidth),
166
+ rect.width * 0.75
167
+ );
168
+ }
169
+
170
+ function handleResizerPointerUp() {
171
+ isResizing = false;
172
+ }
173
+ </script>
174
+
175
+ <div class="playground-studio" class:playground-studio--resizing={isResizing} style="--playground-studio-min-chat-width: {minChatWidth}px">
176
+ <div class="playground-studio__panes" bind:this={splitEl}>
177
+ {#if getPipelinePanelOpen() && resolvedWorkflow && endpointConfig}
178
+ {@const activeId = getActiveExecutionId()}
179
+ {@const executions = getCurrentSession()?.executions ?? []}
180
+
181
+ <div class="playground-studio__pipeline" style="width: {pipelineWidth}px;">
182
+ <PipelinePanel
183
+ pipelineId={activeId}
184
+ workflow={resolvedWorkflow}
185
+ {endpointConfig}
186
+ isPinned={getPinnedExecutionId() !== null}
187
+ {executions}
188
+ latestExecutionId={getLatestExecutionId()}
189
+ onSelectExecution={(id) => playgroundActions.pinExecution(id)}
190
+ refreshTrigger={getPipelineRefreshTrigger()}
191
+ />
192
+ </div>
193
+
194
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
195
+ <div
196
+ class="playground-studio__resizer"
197
+ class:playground-studio__resizer--active={isResizing}
198
+ role="separator"
199
+ aria-orientation="vertical"
200
+ aria-valuenow={Math.round(pipelineWidth)}
201
+ aria-valuemin={0}
202
+ aria-valuemax={Math.round(containerWidth * 0.75)}
203
+ tabindex="0"
204
+ onpointerdown={handleResizerPointerDown}
205
+ onpointermove={handleResizerPointerMove}
206
+ onpointerup={handleResizerPointerUp}
207
+ onpointercancel={handleResizerPointerUp}
208
+ >
209
+ <div class="playground-studio__resizer-handle"></div>
210
+ </div>
211
+ {/if}
212
+
213
+ <div
214
+ class="playground-studio__chat"
215
+ class:playground-studio__chat--solo={!getPipelinePanelOpen()}
216
+ >
217
+ {#if workflowLoading}
218
+ <div class="playground-studio__loading">
219
+ <Icon icon="mdi:loading" class="playground-studio__loading-icon" />
220
+ <p>Loading workflow...</p>
221
+ </div>
222
+ {:else if workflowError}
223
+ <div class="playground-studio__error">
224
+ <Icon icon="mdi:alert-circle" class="playground-studio__error-icon" />
225
+ <p class="playground-studio__error-text">{workflowError}</p>
226
+ <button type="button" class="playground-studio__retry-btn" onclick={loadWorkflow}>
227
+ <Icon icon="mdi:refresh" />
228
+ Retry
229
+ </button>
230
+ </div>
231
+ {:else if resolvedWorkflow}
232
+ {#key initialSessionId}
233
+ <Playground
234
+ {workflowId}
235
+ workflow={resolvedWorkflow}
236
+ {endpointConfig}
237
+ {mode}
238
+ {initialSessionId}
239
+ {config}
240
+ {onClose}
241
+ {onSessionNavigate}
242
+ onTogglePanel={pipelinePanelActions.toggle}
243
+ isPipelinePanelOpen={getPipelinePanelOpen()}
244
+ />
245
+ {/key}
246
+ {/if}
247
+ </div>
248
+ </div>
249
+ </div>
250
+
251
+ <style>
252
+ .playground-studio {
253
+ display: flex;
254
+ flex-direction: column;
255
+ height: 100%;
256
+ min-height: 0;
257
+ overflow: hidden;
258
+ background-color: var(--fd-background);
259
+ }
260
+
261
+ .playground-studio--resizing {
262
+ cursor: col-resize;
263
+ user-select: none;
264
+ }
265
+
266
+ .playground-studio__panes {
267
+ display: flex;
268
+ flex-direction: row;
269
+ flex: 1;
270
+ min-height: 0;
271
+ overflow: hidden;
272
+ }
273
+
274
+ /* Pipeline pane — explicit width set via inline style */
275
+ .playground-studio__pipeline {
276
+ min-width: calc(100% - var(--playground-studio-min-chat-width));
277
+ max-width: 75%;
278
+ overflow: hidden;
279
+ flex-shrink: 0;
280
+ }
281
+
282
+ /* Drag handle between the two panes */
283
+ .playground-studio__resizer {
284
+ width: 8px;
285
+ flex-shrink: 0;
286
+ cursor: col-resize;
287
+ background-color: var(--fd-background);
288
+ border-right: 1px solid var(--fd-border);
289
+ border-left: 1px solid var(--fd-border);
290
+ display: flex;
291
+ align-items: center;
292
+ justify-content: center;
293
+ touch-action: none;
294
+ z-index: 1;
295
+ transition: background-color var(--fd-transition-normal);
296
+ }
297
+
298
+ .playground-studio__resizer:hover,
299
+ .playground-studio__resizer--active {
300
+ background-color: var(--fd-primary-muted);
301
+ }
302
+
303
+ .playground-studio__resizer-handle {
304
+ width: 4px;
305
+ height: 48px;
306
+ background-color: var(--fd-border-strong);
307
+ border-radius: var(--fd-radius-sm);
308
+ transition:
309
+ background-color var(--fd-transition-normal),
310
+ transform var(--fd-transition-normal);
311
+ }
312
+
313
+ .playground-studio__resizer:hover .playground-studio__resizer-handle {
314
+ background-color: var(--fd-primary);
315
+ transform: scaleY(1.2);
316
+ }
317
+
318
+ .playground-studio__resizer--active .playground-studio__resizer-handle {
319
+ background-color: var(--fd-primary-hover);
320
+ transform: scaleY(1.4);
321
+ }
322
+
323
+ /* Chat pane — fills remaining space */
324
+ .playground-studio__chat {
325
+ flex: 1;
326
+ min-width: 0;
327
+ overflow: hidden;
328
+ display: flex;
329
+ flex-direction: column;
330
+ }
331
+
332
+ .playground-studio__chat--solo {
333
+ border-left: 1px solid var(--fd-border);
334
+ border-right: 1px solid var(--fd-border);
335
+ }
336
+
337
+ /* Loading state */
338
+ .playground-studio__loading {
339
+ display: flex;
340
+ flex-direction: column;
341
+ align-items: center;
342
+ justify-content: center;
343
+ height: 100%;
344
+ color: var(--fd-muted-foreground);
345
+ gap: var(--fd-space-md);
346
+ }
347
+
348
+ :global(.playground-studio__loading-icon) {
349
+ font-size: var(--fd-space-6xl);
350
+ animation: studio-spin 1s linear infinite;
351
+ }
352
+
353
+ @keyframes studio-spin {
354
+ from {
355
+ transform: rotate(0deg);
356
+ }
357
+ to {
358
+ transform: rotate(360deg);
359
+ }
360
+ }
361
+
362
+ /* Error state */
363
+ .playground-studio__error {
364
+ display: flex;
365
+ flex-direction: column;
366
+ align-items: center;
367
+ justify-content: center;
368
+ height: 100%;
369
+ padding: var(--fd-space-4xl);
370
+ text-align: center;
371
+ gap: var(--fd-space-md);
372
+ }
373
+
374
+ :global(.playground-studio__error-icon) {
375
+ font-size: var(--fd-space-7xl);
376
+ color: var(--fd-error);
377
+ }
378
+
379
+ .playground-studio__error-text {
380
+ font-size: var(--fd-text-base);
381
+ color: var(--fd-muted-foreground);
382
+ margin: 0;
383
+ max-width: 400px;
384
+ }
385
+
386
+ .playground-studio__retry-btn {
387
+ display: inline-flex;
388
+ align-items: center;
389
+ gap: var(--fd-space-xs);
390
+ padding: var(--fd-space-md) var(--fd-space-3xl);
391
+ border: none;
392
+ border-radius: var(--fd-radius-lg);
393
+ background-color: var(--fd-primary);
394
+ color: var(--fd-primary-foreground);
395
+ font-size: var(--fd-text-base);
396
+ font-weight: 500;
397
+ cursor: pointer;
398
+ transition: background-color var(--fd-transition-normal);
399
+ }
400
+
401
+ .playground-studio__retry-btn:hover {
402
+ background-color: var(--fd-primary-hover);
403
+ }
404
+ </style>
@@ -0,0 +1,30 @@
1
+ import type { Workflow } from '../../types/index.js';
2
+ import type { EndpointConfig } from '../../config/endpoints.js';
3
+ import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
4
+ interface Props {
5
+ /** Target workflow ID */
6
+ workflowId: string;
7
+ /** Pre-loaded workflow — skips internal fetch when provided */
8
+ workflow?: Workflow;
9
+ /** API endpoint configuration */
10
+ endpointConfig?: EndpointConfig;
11
+ /** Display mode (default: standalone) */
12
+ mode?: PlaygroundMode;
13
+ /** Session ID to activate on mount. Changing this prop remounts the Playground. */
14
+ initialSessionId?: string;
15
+ /** Playground configuration options */
16
+ config?: PlaygroundConfig;
17
+ /** Whether the pipeline panel starts open. When omitted the stored preference is used. */
18
+ initialPipelineOpen?: boolean;
19
+ /** Minimum chat panel width in px (default: 760) */
20
+ minChatWidth?: number;
21
+ /** Initial pipeline panel width in px (default: 500) */
22
+ initialPipelineWidth?: number;
23
+ /** Called when session navigation is requested — use for URL-based routing */
24
+ onSessionNavigate?: (sessionId: string) => void;
25
+ /** Called when the playground is closed (embedded / modal mode) */
26
+ onClose?: () => void;
27
+ }
28
+ declare const PlaygroundStudio: import("svelte").Component<Props, {}, "">;
29
+ type PlaygroundStudio = ReturnType<typeof PlaygroundStudio>;
30
+ export default PlaygroundStudio;
@@ -76,7 +76,7 @@ export { setEndpointConfig, getEndpointConfig, nodeApi, workflowApi, api } from
76
76
  export { showSuccess, showError, showWarning, showInfo, showLoading, dismissToast, dismissAllToasts, showPromise, showConfirmation, apiToasts, workflowToasts, pipelineToasts } from '../services/toastService.js';
77
77
  export { NodeExecutionService, nodeExecutionService } from '../services/nodeExecutionService.js';
78
78
  export { PlaygroundService, playgroundService } from '../services/playgroundService.js';
79
- export { getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollTimestamp, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, playgroundActions, createPollingCallback, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestMessageTimestamp } from '../stores/playgroundStore.svelte.js';
79
+ export { getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, playgroundActions, applyServerResponse, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
80
80
  export { saveWorkflow, updateWorkflow, getWorkflow, getWorkflows, deleteWorkflow, getWorkflowCount, initializeSampleWorkflows } from '../services/workflowStorage.js';
81
81
  export { globalSaveWorkflow, globalExportWorkflow } from '../services/globalSave.js';
82
82
  export { fetchPortConfig, validatePortConfig } from '../services/portConfigApi.js';
@@ -119,7 +119,7 @@ export { showSuccess, showError, showWarning, showInfo, showLoading, dismissToas
119
119
  export { NodeExecutionService, nodeExecutionService } from '../services/nodeExecutionService.js';
120
120
  // Playground Service and Store
121
121
  export { PlaygroundService, playgroundService } from '../services/playgroundService.js';
122
- export { getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollTimestamp, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, playgroundActions, createPollingCallback, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestMessageTimestamp } from '../stores/playgroundStore.svelte.js';
122
+ export { getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, playgroundActions, applyServerResponse, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
123
123
  export { saveWorkflow, updateWorkflow, getWorkflow, getWorkflows, deleteWorkflow, getWorkflowCount, initializeSampleWorkflows } from '../services/workflowStorage.js';
124
124
  export { globalSaveWorkflow, globalExportWorkflow } from '../services/globalSave.js';
125
125
  export { fetchPortConfig, validatePortConfig } from '../services/portConfigApi.js';
@@ -111,8 +111,12 @@
111
111
  * ```
112
112
  */
113
113
  export { default as Playground } from '../components/playground/Playground.svelte';
114
+ export { default as PlaygroundStudio } from '../components/playground/PlaygroundStudio.svelte';
115
+ export { default as PlaygroundApp } from '../components/playground/PlaygroundApp.svelte';
114
116
  export { default as PlaygroundModal } from '../components/playground/PlaygroundModal.svelte';
115
117
  export { default as ChatPanel } from '../components/playground/ChatPanel.svelte';
118
+ export { default as PipelinePanel } from '../components/playground/PipelinePanel.svelte';
119
+ export { default as ExecutionList } from '../components/playground/ExecutionList.svelte';
116
120
  export { default as SessionManager } from '../components/playground/SessionManager.svelte';
117
121
  export { default as InputCollector } from '../components/playground/InputCollector.svelte';
118
122
  export { default as ExecutionLogs } from '../components/playground/ExecutionLogs.svelte';
@@ -120,12 +124,13 @@ export { default as MessageBubble } from '../components/playground/MessageBubble
120
124
  export { InterruptBubble, ConfirmationPrompt, ChoicePrompt, TextInputPrompt, FormPrompt, ReviewPrompt } from '../components/interrupt/index.js';
121
125
  export { PlaygroundService, playgroundService } from '../services/playgroundService.js';
122
126
  export { InterruptService, interruptService } from '../services/interruptService.js';
123
- export { getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollTimestamp, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, playgroundActions, createPollingCallback, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestMessageTimestamp } from '../stores/playgroundStore.svelte.js';
124
- export type { PlaygroundSession, PlaygroundMessage, PlaygroundInputField, PlaygroundMessageRequest, PlaygroundMessagesResult, PlaygroundConfig, PlaygroundMode, PlaygroundSessionStatus, PlaygroundMessageRole, PlaygroundMessageLevel, PlaygroundMessageMetadata, PlaygroundApiResponse, PlaygroundSessionsResponse, PlaygroundSessionResponse, PlaygroundMessageResponse, PlaygroundMessagesApiResponse } from '../types/playground.js';
127
+ export { getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, getActiveExecutionId, getPinnedExecutionId, getLatestExecutionId, playgroundActions, applyServerResponse, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
128
+ export { getPipelinePanelOpen, pipelinePanelActions } from '../stores/pipelinePanelStore.svelte.js';
129
+ export type { PlaygroundSession, PlaygroundMessage, PlaygroundInputField, PlaygroundMessageRequest, PlaygroundMessagesResult, PlaygroundConfig, PlaygroundMode, PlaygroundSessionStatus, PlaygroundMessageRole, PlaygroundMessageLevel, PlaygroundMessageMetadata, PlaygroundApiResponse, PlaygroundSessionsResponse, PlaygroundSessionResponse, PlaygroundMessageResponse, PlaygroundMessagesApiResponse, PlaygroundExecution } from '../types/playground.js';
125
130
  export { isChatInputNode, CHAT_INPUT_PATTERNS, defaultShouldStopPolling, defaultIsTerminalStatus, DEFAULT_STOP_POLLING_STATUSES, DEFAULT_TERMINAL_STATUSES } from '../types/playground.js';
126
131
  export type { InterruptType, InterruptStatus, Interrupt, InterruptChoice, InterruptConfig, ConfirmationConfig, ChoiceConfig, TextConfig, FormConfig, ReviewConfig, ReviewChange, ReviewFieldDecision, ReviewResolution, InterruptResolution, InterruptApiResponse, InterruptListResponse, InterruptResponse, InterruptMessageMetadata, InterruptPollingConfig } from '../types/interrupt.js';
127
132
  export { isInterruptMetadata, extractInterruptMetadata, metadataToInterrupt, defaultInterruptPollingConfig } from '../types/interrupt.js';
128
133
  export { getInterruptsMap, getPendingInterruptIds, getPendingInterrupts, getPendingInterruptCount, getResolvedInterrupts, getIsAnySubmitting, interruptActions, getInterrupt, isInterruptPending, isInterruptSubmitting, getInterruptError, getInterruptByMessageId, interruptHasError } from '../stores/interruptStore.svelte.js';
129
134
  export type { InterruptWithState } from '../stores/interruptStore.svelte.js';
130
- export { mountPlayground, unmountPlayground, type PlaygroundMountOptions, type MountedPlayground } from './mount.js';
135
+ export { mountPlayground, unmountPlayground, mountPlaygroundStudio, mountPlaygroundApp, type PlaygroundMountOptions, type PlaygroundStudioMountOptions, type PlaygroundAppMountOptions, type MountedPlayground } from './mount.js';
131
136
  export { createEndpointConfig, defaultEndpointConfig, buildEndpointUrl, type EndpointConfig } from '../config/endpoints.js';
@@ -114,8 +114,12 @@
114
114
  // Playground Components
115
115
  // ============================================================================
116
116
  export { default as Playground } from '../components/playground/Playground.svelte';
117
+ export { default as PlaygroundStudio } from '../components/playground/PlaygroundStudio.svelte';
118
+ export { default as PlaygroundApp } from '../components/playground/PlaygroundApp.svelte';
117
119
  export { default as PlaygroundModal } from '../components/playground/PlaygroundModal.svelte';
118
120
  export { default as ChatPanel } from '../components/playground/ChatPanel.svelte';
121
+ export { default as PipelinePanel } from '../components/playground/PipelinePanel.svelte';
122
+ export { default as ExecutionList } from '../components/playground/ExecutionList.svelte';
119
123
  export { default as SessionManager } from '../components/playground/SessionManager.svelte';
120
124
  export { default as InputCollector } from '../components/playground/InputCollector.svelte';
121
125
  export { default as ExecutionLogs } from '../components/playground/ExecutionLogs.svelte';
@@ -137,17 +141,23 @@ export { InterruptService, interruptService } from '../services/interruptService
137
141
  // ============================================================================
138
142
  export {
139
143
  // Core state getters
140
- getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollTimestamp,
144
+ getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber,
141
145
  // Derived getters
142
146
  getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount,
147
+ // Execution getters (used with PipelinePanel / PlaygroundSplit)
148
+ getActiveExecutionId, getPinnedExecutionId, getLatestExecutionId,
143
149
  // Actions
144
150
  playgroundActions,
145
- // Polling callback factory
146
- createPollingCallback,
151
+ // Server response application (single update path)
152
+ applyServerResponse,
147
153
  // Subscription utility
148
154
  subscribeToSessionStatus,
149
155
  // Utilities
150
- getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestMessageTimestamp } from '../stores/playgroundStore.svelte.js';
156
+ getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
157
+ // ============================================================================
158
+ // Pipeline Panel Store (open/close state, persisted to localStorage)
159
+ // ============================================================================
160
+ export { getPipelinePanelOpen, pipelinePanelActions } from '../stores/pipelinePanelStore.svelte.js';
151
161
  export { isChatInputNode, CHAT_INPUT_PATTERNS, defaultShouldStopPolling, defaultIsTerminalStatus, DEFAULT_STOP_POLLING_STATUSES, DEFAULT_TERMINAL_STATUSES } from '../types/playground.js';
152
162
  export { isInterruptMetadata, extractInterruptMetadata, metadataToInterrupt, defaultInterruptPollingConfig } from '../types/interrupt.js';
153
163
  // ============================================================================
@@ -165,7 +175,7 @@ getInterrupt, isInterruptPending, isInterruptSubmitting, getInterruptError, getI
165
175
  // ============================================================================
166
176
  // Playground Mount Functions (for vanilla JS / Drupal / IIFE integration)
167
177
  // ============================================================================
168
- export { mountPlayground, unmountPlayground } from './mount.js';
178
+ export { mountPlayground, unmountPlayground, mountPlaygroundStudio, mountPlaygroundApp } from './mount.js';
169
179
  // ============================================================================
170
180
  // Endpoint Configuration (re-exported for convenience)
171
181
  // ============================================================================
@@ -46,6 +46,8 @@
46
46
  import type { Workflow } from '../types/index.js';
47
47
  import type { EndpointConfig } from '../config/endpoints.js';
48
48
  import type { PlaygroundMode, PlaygroundConfig, PlaygroundSession, PlaygroundMessagesApiResponse, PlaygroundSessionStatus } from '../types/playground.js';
49
+ import type { PartialSettings, SettingsCategory } from '../types/settings.js';
50
+ import type { NavbarAction } from '../types/navbar.js';
49
51
  /**
50
52
  * Mount options for Playground component
51
53
  */
@@ -83,13 +85,15 @@ export interface PlaygroundMountOptions {
83
85
  */
84
86
  config?: PlaygroundConfig;
85
87
  /**
86
- * Container height (CSS value)
87
- * @default "100%"
88
+ * Container height (CSS value). If omitted, the library does NOT set an
89
+ * inline height — the host's own CSS owns sizing. Pass a definite value
90
+ * (e.g. `"100dvh"`, `"600px"`) only when mounting into an unsized
91
+ * container.
88
92
  */
89
93
  height?: string;
90
94
  /**
91
- * Container width (CSS value)
92
- * @default "100%"
95
+ * Container width (CSS value). If omitted, the library does NOT set an
96
+ * inline width. See `height` for rationale.
93
97
  */
94
98
  width?: string;
95
99
  /**
@@ -103,6 +107,12 @@ export interface PlaygroundMountOptions {
103
107
  * @param previousStatus - The previous session status
104
108
  */
105
109
  onSessionStatusChange?: (status: PlaygroundSessionStatus, previousStatus: PlaygroundSessionStatus) => void;
110
+ /**
111
+ * Optional setting overrides deep-merged over current settings before mount.
112
+ * Theme is re-initialized on every mount regardless. Mirrors mountFlowDropApp's
113
+ * `settings` option.
114
+ */
115
+ settings?: PartialSettings;
106
116
  }
107
117
  /**
108
118
  * Return type for mounted Playground instance
@@ -201,3 +211,52 @@ export declare function mountPlayground(container: HTMLElement, options: Playgro
201
211
  * ```
202
212
  */
203
213
  export declare function unmountPlayground(app: MountedPlayground): void;
214
+ export interface PlaygroundStudioMountOptions extends PlaygroundMountOptions {
215
+ initialPipelineOpen?: boolean;
216
+ minChatWidth?: number;
217
+ initialPipelineWidth?: number;
218
+ onSessionNavigate?: (sessionId: string) => void;
219
+ }
220
+ export declare function mountPlaygroundStudio(container: HTMLElement, options: PlaygroundStudioMountOptions): Promise<MountedPlayground>;
221
+ export interface PlaygroundAppMountOptions extends Omit<PlaygroundStudioMountOptions, 'mode'> {
222
+ /**
223
+ * Display mode. Modal is unsupported — use mountPlayground() for that.
224
+ * @default "standalone"
225
+ */
226
+ mode?: 'standalone' | 'embedded';
227
+ /** Render the FlowDrop Navbar above the playground (default: true). */
228
+ showNavbar?: boolean;
229
+ /** Title shown in the navbar. Falls back to the workflow name, then "Playground". */
230
+ navbarTitle?: string;
231
+ /** Action buttons rendered in the navbar. Passed straight through to <Navbar primaryActions>. */
232
+ primaryActions?: NavbarAction[];
233
+ /** Show the settings gear icon in the navbar (default: true). */
234
+ showSettings?: boolean;
235
+ /** Restrict which settings categories are exposed in the settings modal. */
236
+ settingsCategories?: SettingsCategory[];
237
+ /** Show the "Sync to Cloud" button in the settings modal. */
238
+ showSettingsSyncButton?: boolean;
239
+ /** Show the reset buttons in the settings modal. */
240
+ showSettingsResetButton?: boolean;
241
+ }
242
+ /**
243
+ * Mount the full-page PlaygroundApp (Navbar + PlaygroundStudio) into a container.
244
+ *
245
+ * Use this when you want the same chrome as the FlowDrop editor — logo,
246
+ * branding, and settings modal — wrapped around the playground. For an
247
+ * embeddable split-pane without the navbar, use mountPlaygroundStudio().
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * const app = await mountPlaygroundApp(container, {
252
+ * workflowId: 'wf-123',
253
+ * endpointConfig: createEndpointConfig('/api/flowdrop'),
254
+ * navbarTitle: 'My Workflow',
255
+ * primaryActions: [
256
+ * { label: 'Edit', href: '/workflows/wf-123/edit', icon: 'mdi:pencil-outline', variant: 'secondary' },
257
+ * { label: 'Workflows', href: '/workflows', icon: 'mdi:arrow-left', variant: 'outline' }
258
+ * ]
259
+ * });
260
+ * ```
261
+ */
262
+ export declare function mountPlaygroundApp(container: HTMLElement, options: PlaygroundAppMountOptions): Promise<MountedPlayground>;