@flowdrop/flowdrop 1.10.0 → 1.12.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 (53) hide show
  1. package/dist/api/enhanced-client.d.ts +29 -16
  2. package/dist/api/enhanced-client.js +0 -14
  3. package/dist/components/Navbar.svelte +1 -10
  4. package/dist/components/Navbar.svelte.d.ts +1 -9
  5. package/dist/components/PipelineStatus.svelte +9 -12
  6. package/dist/components/WorkflowEditor.svelte +3 -0
  7. package/dist/components/interrupt/ChoicePrompt.svelte +24 -5
  8. package/dist/components/interrupt/ConfirmationPrompt.svelte +5 -0
  9. package/dist/components/interrupt/InterruptBubble.svelte +12 -0
  10. package/dist/components/interrupt/ReviewPrompt.svelte +20 -0
  11. package/dist/components/interrupt/TextInputPrompt.svelte +5 -0
  12. package/dist/components/nodes/GatewayNode.svelte +2 -6
  13. package/dist/components/nodes/WorkflowNode.svelte +2 -6
  14. package/dist/components/playground/ChatInput.svelte +359 -0
  15. package/dist/components/playground/ChatInput.svelte.d.ts +14 -0
  16. package/dist/components/playground/ChatPanel.svelte +100 -724
  17. package/dist/components/playground/ChatPanel.svelte.d.ts +9 -26
  18. package/dist/components/playground/ControlPanel.svelte +496 -0
  19. package/dist/components/playground/ControlPanel.svelte.d.ts +20 -0
  20. package/dist/components/playground/ExecutionConsole.svelte +163 -0
  21. package/dist/components/playground/ExecutionConsole.svelte.d.ts +14 -0
  22. package/dist/components/playground/MessageStream.svelte +283 -0
  23. package/dist/components/playground/MessageStream.svelte.d.ts +27 -0
  24. package/dist/components/playground/PipelineKanbanView.svelte +284 -0
  25. package/dist/components/playground/PipelineKanbanView.svelte.d.ts +11 -0
  26. package/dist/components/playground/PipelinePanel.svelte +204 -65
  27. package/dist/components/playground/PipelinePanel.svelte.d.ts +3 -1
  28. package/dist/components/playground/PipelineTableView.svelte +376 -0
  29. package/dist/components/playground/PipelineTableView.svelte.d.ts +11 -0
  30. package/dist/components/playground/Playground.svelte +262 -1200
  31. package/dist/components/playground/Playground.svelte.d.ts +0 -13
  32. package/dist/components/playground/PlaygroundApp.svelte +110 -0
  33. package/dist/components/playground/PlaygroundApp.svelte.d.ts +28 -0
  34. package/dist/components/playground/PlaygroundStudio.svelte +35 -61
  35. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -1
  36. package/dist/components/playground/pipelineViewUtils.svelte.d.ts +22 -0
  37. package/dist/components/playground/pipelineViewUtils.svelte.js +77 -0
  38. package/dist/messages/defaults.d.ts +24 -0
  39. package/dist/messages/defaults.js +24 -0
  40. package/dist/playground/index.d.ts +8 -2
  41. package/dist/playground/index.js +8 -1
  42. package/dist/playground/mount.d.ts +59 -4
  43. package/dist/playground/mount.js +102 -9
  44. package/dist/stores/playgroundStore.svelte.d.ts +6 -0
  45. package/dist/stores/playgroundStore.svelte.js +21 -1
  46. package/dist/svelte-app.d.ts +2 -10
  47. package/dist/types/index.d.ts +28 -2
  48. package/dist/types/navbar.d.ts +14 -0
  49. package/dist/types/navbar.js +1 -0
  50. package/dist/types/playground.d.ts +5 -2
  51. package/dist/types/playground.js +5 -7
  52. package/dist/utils/nodeStatus.js +15 -5
  53. package/package.json +1 -1
@@ -1,29 +1,16 @@
1
1
  import type { Workflow } from '../../types/index.js';
2
2
  import type { EndpointConfig } from '../../config/endpoints.js';
3
3
  import type { PlaygroundMode, PlaygroundConfig } from '../../types/playground.js';
4
- /**
5
- * Component props
6
- */
7
4
  interface Props {
8
- /** Target workflow ID */
9
5
  workflowId: string;
10
- /** Pre-loaded workflow (optional, will be fetched if not provided) */
11
6
  workflow?: Workflow;
12
- /** Display mode: embedded (panel) or standalone (page) */
13
7
  mode?: PlaygroundMode;
14
- /** Resume a specific session */
15
8
  initialSessionId?: string;
16
- /** API endpoint configuration */
17
9
  endpointConfig?: EndpointConfig;
18
- /** Playground configuration options */
19
10
  config?: PlaygroundConfig;
20
- /** Callback when playground is closed (for embedded mode) */
21
11
  onClose?: () => void;
22
- /** Callback to toggle the pipeline panel (if undefined, toggle button is hidden) */
23
12
  onTogglePanel?: () => void;
24
- /** Whether the pipeline panel is currently open (for toggle button active state) */
25
13
  isPipelinePanelOpen?: boolean;
26
- /** When provided, session switches and creation navigate to a URL instead of mutating store state */
27
14
  onSessionNavigate?: (sessionId: string) => void;
28
15
  }
29
16
  declare const Playground: import("svelte").Component<Props, {}, "">;
@@ -0,0 +1,110 @@
1
+ <!--
2
+ PlaygroundApp Component
3
+
4
+ Full-page playground wrapper that pairs the FlowDrop Navbar with
5
+ PlaygroundStudio.
6
+
7
+ When importing this component directly (rather than via mountPlaygroundApp),
8
+ call initializeSettings() before mount — the navbar's settings modal reads
9
+ from the settings store.
10
+ -->
11
+
12
+ <script lang="ts">
13
+ import Navbar from '../Navbar.svelte';
14
+ import PlaygroundStudio from './PlaygroundStudio.svelte';
15
+ import type { Workflow } from '../../types/index.js';
16
+ import type { EndpointConfig } from '../../config/endpoints.js';
17
+ import type { PlaygroundConfig } from '../../types/playground.js';
18
+ import type { SettingsCategory } from '../../types/settings.js';
19
+ import type { NavbarAction } from '../../types/navbar.js';
20
+
21
+ interface Props {
22
+ workflowId: string;
23
+ workflow?: Workflow;
24
+ mode?: 'standalone' | 'embedded';
25
+ endpointConfig?: EndpointConfig;
26
+ config?: PlaygroundConfig;
27
+ showNavbar?: boolean;
28
+ navbarTitle?: string;
29
+ primaryActions?: NavbarAction[];
30
+ showSettings?: boolean;
31
+ settingsCategories?: SettingsCategory[];
32
+ showSettingsSyncButton?: boolean;
33
+ showSettingsResetButton?: boolean;
34
+ initialSessionId?: string;
35
+ initialPipelineOpen?: boolean;
36
+ minChatWidth?: number;
37
+ initialPipelineWidth?: number;
38
+ onClose?: () => void;
39
+ onSessionNavigate?: (sessionId: string) => void;
40
+ }
41
+
42
+ let {
43
+ workflowId,
44
+ workflow,
45
+ mode = 'standalone',
46
+ endpointConfig,
47
+ config = {},
48
+ showNavbar = true,
49
+ navbarTitle,
50
+ primaryActions = [],
51
+ showSettings = true,
52
+ settingsCategories,
53
+ showSettingsSyncButton,
54
+ showSettingsResetButton,
55
+ initialSessionId,
56
+ initialPipelineOpen,
57
+ minChatWidth,
58
+ initialPipelineWidth,
59
+ onClose,
60
+ onSessionNavigate
61
+ }: Props = $props();
62
+
63
+ const displayTitle = $derived(navbarTitle ?? workflow?.name ?? 'Playground');
64
+ </script>
65
+
66
+ <div class="fd-playground-app">
67
+ {#if showNavbar}
68
+ <Navbar
69
+ title={displayTitle}
70
+ {primaryActions}
71
+ showStatus={false}
72
+ {showSettings}
73
+ {settingsCategories}
74
+ {showSettingsSyncButton}
75
+ {showSettingsResetButton}
76
+ />
77
+ {/if}
78
+ <div class="fd-playground-app__content">
79
+ <PlaygroundStudio
80
+ {workflowId}
81
+ {workflow}
82
+ {mode}
83
+ {endpointConfig}
84
+ {config}
85
+ {initialSessionId}
86
+ {initialPipelineOpen}
87
+ {minChatWidth}
88
+ {initialPipelineWidth}
89
+ {onClose}
90
+ {onSessionNavigate}
91
+ />
92
+ </div>
93
+ </div>
94
+
95
+ <style>
96
+ .fd-playground-app {
97
+ display: flex;
98
+ flex-direction: column;
99
+ height: 100%;
100
+ width: 100%;
101
+ overflow: hidden;
102
+ background: var(--fd-background);
103
+ }
104
+
105
+ .fd-playground-app__content {
106
+ flex: 1;
107
+ min-height: 0;
108
+ overflow: hidden;
109
+ }
110
+ </style>
@@ -0,0 +1,28 @@
1
+ import type { Workflow } from '../../types/index.js';
2
+ import type { EndpointConfig } from '../../config/endpoints.js';
3
+ import type { PlaygroundConfig } from '../../types/playground.js';
4
+ import type { SettingsCategory } from '../../types/settings.js';
5
+ import type { NavbarAction } from '../../types/navbar.js';
6
+ interface Props {
7
+ workflowId: string;
8
+ workflow?: Workflow;
9
+ mode?: 'standalone' | 'embedded';
10
+ endpointConfig?: EndpointConfig;
11
+ config?: PlaygroundConfig;
12
+ showNavbar?: boolean;
13
+ navbarTitle?: string;
14
+ primaryActions?: NavbarAction[];
15
+ showSettings?: boolean;
16
+ settingsCategories?: SettingsCategory[];
17
+ showSettingsSyncButton?: boolean;
18
+ showSettingsResetButton?: boolean;
19
+ initialSessionId?: string;
20
+ initialPipelineOpen?: boolean;
21
+ minChatWidth?: number;
22
+ initialPipelineWidth?: number;
23
+ onClose?: () => void;
24
+ onSessionNavigate?: (sessionId: string) => void;
25
+ }
26
+ declare const PlaygroundApp: import("svelte").Component<Props, {}, "">;
27
+ type PlaygroundApp = ReturnType<typeof PlaygroundApp>;
28
+ export default PlaygroundApp;
@@ -1,48 +1,5 @@
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
1
  <script lang="ts">
45
- import { onMount } from 'svelte';
2
+ import { onMount, untrack } from 'svelte';
46
3
  import Icon from '@iconify/svelte';
47
4
  import Playground from './Playground.svelte';
48
5
  import PipelinePanel from './PipelinePanel.svelte';
@@ -57,7 +14,7 @@
57
14
  } from '../../stores/playgroundStore.svelte.js';
58
15
  import { setEndpointConfig, workflowApi } from '../../services/api.js';
59
16
  import { logger } from '../../utils/logger.js';
60
- import type { Workflow } from '../../types/index.js';
17
+ import type { Workflow, PipelineViewDef } from '../../types/index.js';
61
18
  import type { EndpointConfig } from '../../config/endpoints.js';
62
19
  import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
63
20
 
@@ -84,6 +41,8 @@
84
41
  onSessionNavigate?: (sessionId: string) => void;
85
42
  /** Called when the playground is closed (embedded / modal mode) */
86
43
  onClose?: () => void;
44
+ /** Additional pipeline views injected by the consumer */
45
+ extraPipelineViews?: PipelineViewDef[];
87
46
  }
88
47
 
89
48
  let {
@@ -98,19 +57,18 @@
98
57
  initialPipelineWidth = 500,
99
58
  onSessionNavigate,
100
59
  onClose,
60
+ extraPipelineViews = [],
101
61
  }: Props = $props();
102
62
 
103
- // svelte-ignore state_referenced_locally
104
63
  let resolvedWorkflow = $state<Workflow | null>(workflowProp ?? null);
105
- // svelte-ignore state_referenced_locally
106
64
  let workflowLoading = $state(workflowProp === undefined);
107
65
  let workflowError = $state<string | null>(null);
108
66
 
109
67
  let splitEl = $state<HTMLElement | null>(null);
110
- // svelte-ignore state_referenced_locally
111
68
  let pipelineWidth = $state(initialPipelineWidth);
112
69
  let isResizing = $state(false);
113
70
  let containerWidth = $state(0);
71
+ let dragContainerLeft = 0;
114
72
 
115
73
  $effect(() => {
116
74
  if (!splitEl) return;
@@ -121,6 +79,12 @@
121
79
  return () => observer.disconnect();
122
80
  });
123
81
 
82
+ $effect(() => {
83
+ if (containerWidth > 0) {
84
+ pipelineWidth = clampPipelineWidth(untrack(() => pipelineWidth));
85
+ }
86
+ });
87
+
124
88
  onMount(() => {
125
89
  pipelinePanelActions.init();
126
90
  if (initialPipelineOpen !== undefined) {
@@ -153,23 +117,36 @@
153
117
  }
154
118
  }
155
119
 
120
+ function clampPipelineWidth(w: number): number {
121
+ if (!containerWidth) return Math.max(w, 0);
122
+ return Math.min(Math.max(w, containerWidth - minChatWidth), containerWidth * 0.75);
123
+ }
124
+
156
125
  function handleResizerPointerDown(e: PointerEvent) {
126
+ if (splitEl) dragContainerLeft = splitEl.getBoundingClientRect().left;
157
127
  isResizing = true;
158
128
  (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
159
129
  }
160
130
 
161
131
  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
- );
132
+ if (!isResizing) return;
133
+ pipelineWidth = clampPipelineWidth(e.clientX - dragContainerLeft);
168
134
  }
169
135
 
170
136
  function handleResizerPointerUp() {
171
137
  isResizing = false;
172
138
  }
139
+
140
+ function handleResizerKeyDown(e: KeyboardEvent) {
141
+ const step = e.shiftKey ? 50 : 20;
142
+ if (e.key === 'ArrowLeft') {
143
+ e.preventDefault();
144
+ pipelineWidth = clampPipelineWidth(pipelineWidth - step);
145
+ } else if (e.key === 'ArrowRight') {
146
+ e.preventDefault();
147
+ pipelineWidth = clampPipelineWidth(pipelineWidth + step);
148
+ }
149
+ }
173
150
  </script>
174
151
 
175
152
  <div class="playground-studio" class:playground-studio--resizing={isResizing} style="--playground-studio-min-chat-width: {minChatWidth}px">
@@ -188,10 +165,10 @@
188
165
  latestExecutionId={getLatestExecutionId()}
189
166
  onSelectExecution={(id) => playgroundActions.pinExecution(id)}
190
167
  refreshTrigger={getPipelineRefreshTrigger()}
168
+ extraViews={extraPipelineViews}
191
169
  />
192
170
  </div>
193
171
 
194
- <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
195
172
  <div
196
173
  class="playground-studio__resizer"
197
174
  class:playground-studio__resizer--active={isResizing}
@@ -200,11 +177,13 @@
200
177
  aria-valuenow={Math.round(pipelineWidth)}
201
178
  aria-valuemin={0}
202
179
  aria-valuemax={Math.round(containerWidth * 0.75)}
180
+ aria-label="Resize pipeline panel"
203
181
  tabindex="0"
204
182
  onpointerdown={handleResizerPointerDown}
205
183
  onpointermove={handleResizerPointerMove}
206
184
  onpointerup={handleResizerPointerUp}
207
185
  onpointercancel={handleResizerPointerUp}
186
+ onkeydown={handleResizerKeyDown}
208
187
  >
209
188
  <div class="playground-studio__resizer-handle"></div>
210
189
  </div>
@@ -271,10 +250,8 @@
271
250
  overflow: hidden;
272
251
  }
273
252
 
274
- /* Pipeline pane — explicit width set via inline style */
253
+ /* Pipeline pane — explicit width driven by JS; clamping keeps it in bounds */
275
254
  .playground-studio__pipeline {
276
- min-width: calc(100% - var(--playground-studio-min-chat-width));
277
- max-width: 75%;
278
255
  overflow: hidden;
279
256
  flex-shrink: 0;
280
257
  }
@@ -351,9 +328,6 @@
351
328
  }
352
329
 
353
330
  @keyframes studio-spin {
354
- from {
355
- transform: rotate(0deg);
356
- }
357
331
  to {
358
332
  transform: rotate(360deg);
359
333
  }
@@ -1,4 +1,4 @@
1
- import type { Workflow } from '../../types/index.js';
1
+ import type { Workflow, PipelineViewDef } from '../../types/index.js';
2
2
  import type { EndpointConfig } from '../../config/endpoints.js';
3
3
  import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
4
4
  interface Props {
@@ -24,6 +24,8 @@ interface Props {
24
24
  onSessionNavigate?: (sessionId: string) => void;
25
25
  /** Called when the playground is closed (embedded / modal mode) */
26
26
  onClose?: () => void;
27
+ /** Additional pipeline views injected by the consumer */
28
+ extraPipelineViews?: PipelineViewDef[];
27
29
  }
28
30
  declare const PlaygroundStudio: import("svelte").Component<Props, {}, "">;
29
31
  type PlaygroundStudio = ReturnType<typeof PlaygroundStudio>;
@@ -0,0 +1,22 @@
1
+ import type { EndpointConfig } from '../../config/endpoints.js';
2
+ import type { NodeExecutionStatus, KanbanColumnDef } from '../../types/index.js';
3
+ export type NodeStatus = NodeExecutionStatus;
4
+ export interface NodeStatusData {
5
+ status: string;
6
+ last_executed?: string | null;
7
+ execution_time?: number | null;
8
+ error?: string | null;
9
+ }
10
+ export declare function resolveStatus(raw: NodeStatusData | undefined): NodeStatus;
11
+ /**
12
+ * Creates a reactive pipeline data fetcher.
13
+ * `endpointConfig` is used once to construct the API client — it must be stable.
14
+ * `getPipelineId` is called on every fetch so pipeline ID changes are picked up.
15
+ */
16
+ export declare function createPipelineDataFetcher(getPipelineId: () => string, endpointConfig: EndpointConfig): {
17
+ readonly nodeStatusMap: Record<string, NodeStatusData>;
18
+ readonly kanbanConfig: KanbanColumnDef[] | null;
19
+ readonly isLoading: boolean;
20
+ readonly isError: boolean;
21
+ fetchData: () => Promise<void>;
22
+ };
@@ -0,0 +1,77 @@
1
+ import { EnhancedFlowDropApiClient } from '../../api/enhanced-client.js';
2
+ import { logger } from '../../utils/logger.js';
3
+ const KNOWN_STATUSES = new Set([
4
+ 'idle', 'pending', 'running', 'paused', 'interrupted',
5
+ 'completed', 'skipped', 'failed', 'cancelled'
6
+ ]);
7
+ export function resolveStatus(raw) {
8
+ if (!raw)
9
+ return 'pending';
10
+ const s = raw.status || 'pending';
11
+ if (!KNOWN_STATUSES.has(s)) {
12
+ logger.warn(`[FlowDrop] Unknown node status from server: "${s}" — falling back to "pending"`);
13
+ return 'pending';
14
+ }
15
+ return s;
16
+ }
17
+ /**
18
+ * Creates a reactive pipeline data fetcher.
19
+ * `endpointConfig` is used once to construct the API client — it must be stable.
20
+ * `getPipelineId` is called on every fetch so pipeline ID changes are picked up.
21
+ */
22
+ export function createPipelineDataFetcher(getPipelineId, endpointConfig) {
23
+ const client = new EnhancedFlowDropApiClient(endpointConfig);
24
+ let nodeStatusMap = $state({});
25
+ let kanbanConfig = $state(null);
26
+ let isLoading = $state(false);
27
+ let isError = $state(false);
28
+ async function fetchData() {
29
+ try {
30
+ isLoading = true;
31
+ isError = false;
32
+ const data = await client.getPipelineData(getPipelineId());
33
+ const map = {};
34
+ for (const [nodeId, info] of Object.entries(data.node_statuses)) {
35
+ map[nodeId] = {
36
+ status: info.status,
37
+ last_executed: info.last_executed,
38
+ execution_time: info.execution_time,
39
+ error: info.error,
40
+ };
41
+ }
42
+ nodeStatusMap = map;
43
+ if (data.kanban_config?.columns) {
44
+ // Server sends statuses as string[]; trust the server and cast at this
45
+ // boundary. resolveStatus() handles unknown values at read time.
46
+ kanbanConfig = data.kanban_config.columns.map((col) => ({
47
+ key: col.key,
48
+ label: col.label,
49
+ statuses: col.statuses,
50
+ icon: col.icon,
51
+ color: col.color,
52
+ }));
53
+ }
54
+ }
55
+ catch {
56
+ isError = true;
57
+ }
58
+ finally {
59
+ isLoading = false;
60
+ }
61
+ }
62
+ return {
63
+ get nodeStatusMap() {
64
+ return nodeStatusMap;
65
+ },
66
+ get kanbanConfig() {
67
+ return kanbanConfig;
68
+ },
69
+ get isLoading() {
70
+ return isLoading;
71
+ },
72
+ get isError() {
73
+ return isError;
74
+ },
75
+ fetchData
76
+ };
77
+ }
@@ -328,6 +328,30 @@ export declare const defaultMessages: {
328
328
  n: number;
329
329
  }) => string;
330
330
  };
331
+ readonly executionConsole: {
332
+ readonly header: "Execution";
333
+ readonly noExecutionTitle: "No execution yet";
334
+ readonly noExecutionText: "Create or select a session below, then run your workflow to see execution output here.";
335
+ readonly readyTitle: "Ready to run";
336
+ readonly readyText: "Use the controls below to start the workflow. Output and interactive prompts will appear here.";
337
+ readonly newSession: "New session";
338
+ };
339
+ readonly controlPanel: {
340
+ readonly sessionsLabel: "Sessions";
341
+ readonly noSession: "No session";
342
+ readonly switchSession: "Switch session";
343
+ readonly newSession: "New session";
344
+ readonly pipeline: "Pipeline";
345
+ readonly showPipeline: "Show pipeline";
346
+ readonly hidePipeline: "Hide pipeline";
347
+ readonly refresh: "Refresh";
348
+ readonly refreshTitle: "Refresh status";
349
+ readonly logs: "Logs";
350
+ readonly showLogs: "Show log messages";
351
+ readonly hideLogs: "Hide log messages";
352
+ readonly deleteSession: "Delete session";
353
+ readonly messageStreamLabel: "Execution output";
354
+ };
331
355
  };
332
356
  readonly nodes: {
333
357
  readonly notes: {
@@ -300,6 +300,30 @@ export const defaultMessages = {
300
300
  minutesAgo: ({ n }) => `${n}m ago`,
301
301
  hoursAgo: ({ n }) => `${n}h ago`,
302
302
  daysAgo: ({ n }) => `${n}d ago`
303
+ },
304
+ executionConsole: {
305
+ header: 'Execution',
306
+ noExecutionTitle: 'No execution yet',
307
+ noExecutionText: 'Create or select a session below, then run your workflow to see execution output here.',
308
+ readyTitle: 'Ready to run',
309
+ readyText: 'Use the controls below to start the workflow. Output and interactive prompts will appear here.',
310
+ newSession: 'New session'
311
+ },
312
+ controlPanel: {
313
+ sessionsLabel: 'Sessions',
314
+ noSession: 'No session',
315
+ switchSession: 'Switch session',
316
+ newSession: 'New session',
317
+ pipeline: 'Pipeline',
318
+ showPipeline: 'Show pipeline',
319
+ hidePipeline: 'Hide pipeline',
320
+ refresh: 'Refresh',
321
+ refreshTitle: 'Refresh status',
322
+ logs: 'Logs',
323
+ showLogs: 'Show log messages',
324
+ hideLogs: 'Hide log messages',
325
+ deleteSession: 'Delete session',
326
+ messageStreamLabel: 'Execution output'
303
327
  }
304
328
  },
305
329
  nodes: {
@@ -112,8 +112,13 @@
112
112
  */
113
113
  export { default as Playground } from '../components/playground/Playground.svelte';
114
114
  export { default as PlaygroundStudio } from '../components/playground/PlaygroundStudio.svelte';
115
+ export { default as PlaygroundApp } from '../components/playground/PlaygroundApp.svelte';
115
116
  export { default as PlaygroundModal } from '../components/playground/PlaygroundModal.svelte';
116
117
  export { default as ChatPanel } from '../components/playground/ChatPanel.svelte';
118
+ export { default as MessageStream } from '../components/playground/MessageStream.svelte';
119
+ export { default as ChatInput } from '../components/playground/ChatInput.svelte';
120
+ export { default as ExecutionConsole } from '../components/playground/ExecutionConsole.svelte';
121
+ export { default as ControlPanel } from '../components/playground/ControlPanel.svelte';
117
122
  export { default as PipelinePanel } from '../components/playground/PipelinePanel.svelte';
118
123
  export { default as ExecutionList } from '../components/playground/ExecutionList.svelte';
119
124
  export { default as SessionManager } from '../components/playground/SessionManager.svelte';
@@ -123,7 +128,7 @@ export { default as MessageBubble } from '../components/playground/MessageBubble
123
128
  export { InterruptBubble, ConfirmationPrompt, ChoicePrompt, TextInputPrompt, FormPrompt, ReviewPrompt } from '../components/interrupt/index.js';
124
129
  export { PlaygroundService, playgroundService } from '../services/playgroundService.js';
125
130
  export { InterruptService, interruptService } from '../services/interruptService.js';
126
- 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';
131
+ export { getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, getActiveExecutionId, getPinnedExecutionId, getLatestExecutionId, getShowLogs, playgroundActions, applyServerResponse, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
127
132
  export { getPipelinePanelOpen, pipelinePanelActions } from '../stores/pipelinePanelStore.svelte.js';
128
133
  export type { PlaygroundSession, PlaygroundMessage, PlaygroundInputField, PlaygroundMessageRequest, PlaygroundMessagesResult, PlaygroundConfig, PlaygroundMode, PlaygroundSessionStatus, PlaygroundMessageRole, PlaygroundMessageLevel, PlaygroundMessageMetadata, PlaygroundApiResponse, PlaygroundSessionsResponse, PlaygroundSessionResponse, PlaygroundMessageResponse, PlaygroundMessagesApiResponse, PlaygroundExecution } from '../types/playground.js';
129
134
  export { isChatInputNode, CHAT_INPUT_PATTERNS, defaultShouldStopPolling, defaultIsTerminalStatus, DEFAULT_STOP_POLLING_STATUSES, DEFAULT_TERMINAL_STATUSES } from '../types/playground.js';
@@ -131,5 +136,6 @@ export type { InterruptType, InterruptStatus, Interrupt, InterruptChoice, Interr
131
136
  export { isInterruptMetadata, extractInterruptMetadata, metadataToInterrupt, defaultInterruptPollingConfig } from '../types/interrupt.js';
132
137
  export { getInterruptsMap, getPendingInterruptIds, getPendingInterrupts, getPendingInterruptCount, getResolvedInterrupts, getIsAnySubmitting, interruptActions, getInterrupt, isInterruptPending, isInterruptSubmitting, getInterruptError, getInterruptByMessageId, interruptHasError } from '../stores/interruptStore.svelte.js';
133
138
  export type { InterruptWithState } from '../stores/interruptStore.svelte.js';
134
- export { mountPlayground, unmountPlayground, mountPlaygroundStudio, type PlaygroundMountOptions, type PlaygroundStudioMountOptions, type MountedPlayground } from './mount.js';
139
+ export { mountPlayground, unmountPlayground, mountPlaygroundStudio, mountPlaygroundApp, type PlaygroundMountOptions, type PlaygroundStudioMountOptions, type PlaygroundAppMountOptions, type MountedPlayground } from './mount.js';
140
+ export type { PipelineViewDef, PipelineViewProps } from '../types/index.js';
135
141
  export { createEndpointConfig, defaultEndpointConfig, buildEndpointUrl, type EndpointConfig } from '../config/endpoints.js';
@@ -115,8 +115,13 @@
115
115
  // ============================================================================
116
116
  export { default as Playground } from '../components/playground/Playground.svelte';
117
117
  export { default as PlaygroundStudio } from '../components/playground/PlaygroundStudio.svelte';
118
+ export { default as PlaygroundApp } from '../components/playground/PlaygroundApp.svelte';
118
119
  export { default as PlaygroundModal } from '../components/playground/PlaygroundModal.svelte';
119
120
  export { default as ChatPanel } from '../components/playground/ChatPanel.svelte';
121
+ export { default as MessageStream } from '../components/playground/MessageStream.svelte';
122
+ export { default as ChatInput } from '../components/playground/ChatInput.svelte';
123
+ export { default as ExecutionConsole } from '../components/playground/ExecutionConsole.svelte';
124
+ export { default as ControlPanel } from '../components/playground/ControlPanel.svelte';
120
125
  export { default as PipelinePanel } from '../components/playground/PipelinePanel.svelte';
121
126
  export { default as ExecutionList } from '../components/playground/ExecutionList.svelte';
122
127
  export { default as SessionManager } from '../components/playground/SessionManager.svelte';
@@ -145,6 +150,8 @@ getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage,
145
150
  getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount,
146
151
  // Execution getters (used with PipelinePanel / PlaygroundSplit)
147
152
  getActiveExecutionId, getPinnedExecutionId, getLatestExecutionId,
153
+ // UI state
154
+ getShowLogs,
148
155
  // Actions
149
156
  playgroundActions,
150
157
  // Server response application (single update path)
@@ -174,7 +181,7 @@ getInterrupt, isInterruptPending, isInterruptSubmitting, getInterruptError, getI
174
181
  // ============================================================================
175
182
  // Playground Mount Functions (for vanilla JS / Drupal / IIFE integration)
176
183
  // ============================================================================
177
- export { mountPlayground, unmountPlayground, mountPlaygroundStudio } from './mount.js';
184
+ export { mountPlayground, unmountPlayground, mountPlaygroundStudio, mountPlaygroundApp } from './mount.js';
178
185
  // ============================================================================
179
186
  // Endpoint Configuration (re-exported for convenience)
180
187
  // ============================================================================