@flowdrop/flowdrop 1.15.0 → 2.0.0-beta.2

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 (235) hide show
  1. package/CHANGELOG.md +508 -0
  2. package/MIGRATION-2.0.md +629 -0
  3. package/README.md +23 -23
  4. package/dist/adapters/WorkflowAdapter.d.ts +1 -1
  5. package/dist/adapters/WorkflowAdapter.js +14 -8
  6. package/dist/adapters/agentspec/AgentSpecAdapter.js +7 -7
  7. package/dist/api/enhanced-client.js +6 -11
  8. package/dist/chat/batchFeedback.d.ts +39 -0
  9. package/dist/chat/batchFeedback.js +51 -0
  10. package/dist/commands/executor.js +15 -1
  11. package/dist/commands/storeIntegration.svelte.d.ts +4 -1
  12. package/dist/commands/storeIntegration.svelte.js +26 -21
  13. package/dist/commands/types.d.ts +2 -0
  14. package/dist/components/App.svelte +163 -192
  15. package/dist/components/App.svelte.d.ts +47 -8
  16. package/dist/components/ConfigForm.svelte +77 -49
  17. package/dist/components/ConfigModal.svelte +7 -2
  18. package/dist/components/ConnectionLine.svelte +4 -2
  19. package/dist/components/Navbar.svelte +61 -1
  20. package/dist/components/NodeSidebar.svelte +27 -45
  21. package/dist/components/NodeStatusOverlay.svelte +94 -6
  22. package/dist/components/NodeSwapPicker.svelte +10 -8
  23. package/dist/components/PipelineStatus.svelte +22 -68
  24. package/dist/components/PipelineStatus.svelte.d.ts +3 -0
  25. package/dist/components/PortCoordinateTracker.svelte +5 -6
  26. package/dist/components/SchemaForm.stories.svelte +1 -3
  27. package/dist/components/SchemaForm.svelte +22 -27
  28. package/dist/components/SchemaForm.svelte.d.ts +0 -8
  29. package/dist/components/SettingsModal.svelte +8 -3
  30. package/dist/components/SettingsPanel.svelte +20 -4
  31. package/dist/components/SwapMappingEditor.svelte +67 -49
  32. package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
  33. package/dist/components/UniversalNode.svelte +9 -7
  34. package/dist/components/WorkflowEditor.svelte +121 -111
  35. package/dist/components/WorkflowEditor.svelte.d.ts +21 -10
  36. package/dist/components/chat/AIChatPanel.svelte +98 -89
  37. package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
  38. package/dist/components/chat/CommandPreview.svelte +2 -1
  39. package/dist/components/console/CommandConsole.svelte +7 -5
  40. package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
  41. package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
  42. package/dist/components/console/ConsoleInput.svelte +15 -6
  43. package/dist/components/console/ConsoleOutput.svelte +2 -1
  44. package/dist/components/form/FormArray.svelte +5 -9
  45. package/dist/components/form/FormArray.svelte.d.ts +2 -1
  46. package/dist/components/form/FormAutocomplete.svelte +16 -15
  47. package/dist/components/form/FormField.svelte +4 -2
  48. package/dist/components/form/FormFieldLight.svelte +34 -3
  49. package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
  50. package/dist/components/form/FormMarkdownEditor.svelte +9 -4
  51. package/dist/components/form/FormRangeField.svelte +1 -0
  52. package/dist/components/form/FormTemplateEditor.svelte +11 -3
  53. package/dist/components/form/FormToggle.svelte +5 -12
  54. package/dist/components/form/FormToggle.svelte.d.ts +4 -2
  55. package/dist/components/form/FormUISchemaRenderer.svelte +3 -1
  56. package/dist/components/form/templateAutocomplete.js +1 -5
  57. package/dist/components/form/types.d.ts +1 -14
  58. package/dist/components/interrupt/FormPrompt.svelte +3 -2
  59. package/dist/components/interrupt/InterruptBubble.svelte +25 -17
  60. package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
  61. package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
  62. package/dist/components/layouts/MainLayout.svelte +20 -13
  63. package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
  64. package/dist/components/nodes/AtomNode.svelte +17 -5
  65. package/dist/components/nodes/GatewayNode.svelte +19 -10
  66. package/dist/components/nodes/IdeaNode.svelte +7 -0
  67. package/dist/components/nodes/SimpleNode.svelte +11 -6
  68. package/dist/components/nodes/SquareNode.svelte +15 -8
  69. package/dist/components/nodes/TerminalNode.svelte +9 -4
  70. package/dist/components/nodes/ToolNode.svelte +7 -1
  71. package/dist/components/nodes/WorkflowNode.svelte +16 -7
  72. package/dist/components/playground/ChatInput.svelte +11 -14
  73. package/dist/components/playground/ChatPanel.svelte +6 -49
  74. package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
  75. package/dist/components/playground/ControlPanel.svelte +134 -123
  76. package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
  77. package/dist/components/playground/ExecutionLogs.svelte +11 -9
  78. package/dist/components/playground/InputCollector.svelte +11 -9
  79. package/dist/components/playground/MessageStream.svelte +17 -23
  80. package/dist/components/playground/PipelineKanbanView.svelte +69 -8
  81. package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
  82. package/dist/components/playground/PipelinePanel.svelte +31 -8
  83. package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
  84. package/dist/components/playground/PipelineTableView.svelte +188 -44
  85. package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
  86. package/dist/components/playground/Playground.svelte +154 -105
  87. package/dist/components/playground/Playground.svelte.d.ts +5 -0
  88. package/dist/components/playground/PlaygroundApp.svelte +11 -1
  89. package/dist/components/playground/PlaygroundApp.svelte.d.ts +6 -0
  90. package/dist/components/playground/PlaygroundModal.svelte +18 -3
  91. package/dist/components/playground/PlaygroundModal.svelte.d.ts +6 -0
  92. package/dist/components/playground/PlaygroundStudio.svelte +40 -32
  93. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +6 -0
  94. package/dist/components/playground/SessionManager.svelte +9 -12
  95. package/dist/components/playground/pipelineViewUtils.svelte.d.ts +30 -1
  96. package/dist/components/playground/pipelineViewUtils.svelte.js +40 -3
  97. package/dist/config/endpoints.d.ts +23 -7
  98. package/dist/config/endpoints.js +30 -10
  99. package/dist/core/index.d.ts +5 -6
  100. package/dist/core/index.js +8 -12
  101. package/dist/display/index.d.ts +6 -3
  102. package/dist/display/index.js +7 -5
  103. package/dist/editor/index.d.ts +20 -21
  104. package/dist/editor/index.js +26 -36
  105. package/dist/form/code.d.ts +25 -15
  106. package/dist/form/code.js +44 -41
  107. package/dist/form/fieldRegistry.d.ts +17 -13
  108. package/dist/form/fieldRegistry.js +32 -12
  109. package/dist/form/full.d.ts +19 -14
  110. package/dist/form/full.js +26 -28
  111. package/dist/form/index.d.ts +3 -4
  112. package/dist/form/index.js +6 -5
  113. package/dist/form/markdown.d.ts +13 -8
  114. package/dist/form/markdown.js +22 -23
  115. package/dist/helpers/proximityConnect.d.ts +3 -2
  116. package/dist/helpers/proximityConnect.js +2 -5
  117. package/dist/helpers/workflowEditorHelper.d.ts +14 -5
  118. package/dist/helpers/workflowEditorHelper.js +28 -25
  119. package/dist/index.d.ts +28 -24
  120. package/dist/index.js +27 -50
  121. package/dist/messages/defaults.d.ts +2 -5
  122. package/dist/messages/defaults.js +3 -6
  123. package/dist/messages/index.d.ts +0 -1
  124. package/dist/messages/index.js +0 -1
  125. package/dist/mocks/app-forms.d.ts +6 -2
  126. package/dist/mocks/app-forms.js +11 -4
  127. package/dist/openapi/v1/openapi.yaml +3 -3
  128. package/dist/playground/index.d.ts +4 -5
  129. package/dist/playground/index.js +4 -32
  130. package/dist/playground/mount.d.ts +25 -0
  131. package/dist/playground/mount.js +50 -20
  132. package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
  133. package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
  134. package/dist/registry/builtinFormats.d.ts +9 -18
  135. package/dist/registry/builtinFormats.js +9 -39
  136. package/dist/registry/builtinNodeTypes.d.ts +53 -0
  137. package/dist/registry/builtinNodeTypes.js +67 -0
  138. package/dist/registry/builtinNodes.d.ts +2 -64
  139. package/dist/registry/builtinNodes.js +7 -103
  140. package/dist/registry/index.d.ts +3 -4
  141. package/dist/registry/index.js +4 -6
  142. package/dist/registry/nodeComponentRegistry.d.ts +182 -15
  143. package/dist/registry/nodeComponentRegistry.js +235 -17
  144. package/dist/registry/workflowFormatRegistry.d.ts +14 -9
  145. package/dist/registry/workflowFormatRegistry.js +24 -8
  146. package/dist/{schema → schemas}/index.d.ts +2 -2
  147. package/dist/{schema → schemas}/index.js +2 -2
  148. package/dist/schemas/v1/workflow.schema.json +3 -3
  149. package/dist/services/agentSpecExecutionService.d.ts +0 -2
  150. package/dist/services/agentSpecExecutionService.js +0 -3
  151. package/dist/services/apiVariableService.d.ts +2 -1
  152. package/dist/services/apiVariableService.js +16 -47
  153. package/dist/services/autoSaveService.d.ts +7 -0
  154. package/dist/services/autoSaveService.js +6 -4
  155. package/dist/services/categoriesApi.js +3 -6
  156. package/dist/services/chatService.d.ts +9 -4
  157. package/dist/services/chatService.js +23 -28
  158. package/dist/services/draftStorage.d.ts +129 -13
  159. package/dist/services/draftStorage.js +185 -37
  160. package/dist/services/dynamicSchemaService.d.ts +2 -1
  161. package/dist/services/dynamicSchemaService.js +5 -22
  162. package/dist/services/globalSave.d.ts +13 -12
  163. package/dist/services/globalSave.js +29 -51
  164. package/dist/services/historyService.d.ts +9 -3
  165. package/dist/services/historyService.js +9 -3
  166. package/dist/services/interruptService.d.ts +15 -9
  167. package/dist/services/interruptService.js +35 -37
  168. package/dist/services/nodeExecutionService.d.ts +18 -3
  169. package/dist/services/nodeExecutionService.js +71 -45
  170. package/dist/services/playgroundService.d.ts +16 -10
  171. package/dist/services/playgroundService.js +42 -43
  172. package/dist/services/portConfigApi.js +3 -6
  173. package/dist/services/settingsService.d.ts +9 -4
  174. package/dist/services/settingsService.js +23 -12
  175. package/dist/services/variableService.d.ts +2 -1
  176. package/dist/services/variableService.js +2 -2
  177. package/dist/services/workflowStorage.js +6 -6
  178. package/dist/stores/apiContext.d.ts +56 -0
  179. package/dist/stores/apiContext.js +80 -0
  180. package/dist/stores/categoriesStore.svelte.d.ts +28 -23
  181. package/dist/stores/categoriesStore.svelte.js +69 -64
  182. package/dist/stores/getInstance.svelte.d.ts +39 -0
  183. package/dist/stores/getInstance.svelte.js +65 -0
  184. package/dist/stores/historyStore.svelte.d.ts +77 -93
  185. package/dist/stores/historyStore.svelte.js +134 -160
  186. package/dist/stores/instanceContainer.svelte.d.ts +111 -0
  187. package/dist/stores/instanceContainer.svelte.js +114 -0
  188. package/dist/stores/interruptStore.svelte.d.ts +112 -82
  189. package/dist/stores/interruptStore.svelte.js +253 -226
  190. package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
  191. package/dist/stores/pipelinePanelStore.svelte.js +61 -14
  192. package/dist/stores/playgroundStore.svelte.d.ts +169 -222
  193. package/dist/stores/playgroundStore.svelte.js +513 -580
  194. package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
  195. package/dist/stores/portCoordinateStore.svelte.js +109 -98
  196. package/dist/stores/settingsStore.svelte.d.ts +4 -1
  197. package/dist/stores/settingsStore.svelte.js +47 -12
  198. package/dist/stores/workflowStore.svelte.d.ts +178 -213
  199. package/dist/stores/workflowStore.svelte.js +449 -501
  200. package/dist/stories/EdgeDecorator.svelte +5 -2
  201. package/dist/stories/NodeDecorator.svelte +5 -3
  202. package/dist/svelte-app.d.ts +60 -10
  203. package/dist/svelte-app.js +159 -54
  204. package/dist/types/auth.d.ts +9 -51
  205. package/dist/types/auth.js +4 -54
  206. package/dist/types/events.d.ts +6 -3
  207. package/dist/types/index.d.ts +37 -5
  208. package/dist/types/index.js +0 -1
  209. package/dist/types/navbar.d.ts +7 -0
  210. package/dist/types/playground.d.ts +18 -3
  211. package/dist/types/settings.d.ts +13 -0
  212. package/dist/types/settings.js +1 -0
  213. package/dist/utils/colors.d.ts +47 -21
  214. package/dist/utils/colors.js +69 -68
  215. package/dist/utils/connections.d.ts +9 -15
  216. package/dist/utils/connections.js +13 -32
  217. package/dist/utils/duration.d.ts +13 -0
  218. package/dist/utils/duration.js +45 -0
  219. package/dist/utils/edgeStyling.js +9 -5
  220. package/dist/utils/fetchWithAuth.d.ts +36 -15
  221. package/dist/utils/fetchWithAuth.js +53 -23
  222. package/dist/utils/icons.d.ts +5 -2
  223. package/dist/utils/icons.js +6 -5
  224. package/dist/utils/nodeSwap.d.ts +6 -2
  225. package/dist/utils/nodeSwap.js +62 -126
  226. package/dist/utils/nodeTypes.d.ts +17 -8
  227. package/dist/utils/nodeTypes.js +27 -20
  228. package/dist/utils/performanceUtils.js +7 -0
  229. package/package.json +7 -5
  230. package/dist/messages/deprecation.d.ts +0 -20
  231. package/dist/messages/deprecation.js +0 -33
  232. package/dist/registry/plugin.d.ts +0 -215
  233. package/dist/registry/plugin.js +0 -249
  234. package/dist/services/api.d.ts +0 -129
  235. package/dist/services/api.js +0 -217
@@ -10,7 +10,9 @@
10
10
  import Icon from '@iconify/svelte';
11
11
  import Playground from './Playground.svelte';
12
12
  import type { Workflow } from '../../types/index.js';
13
+ import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
13
14
  import type { EndpointConfig } from '../../config/endpoints.js';
15
+ import type { AuthProvider } from '../../types/auth.js';
14
16
  import type { PlaygroundConfig } from '../../types/playground.js';
15
17
  import { m } from '../../messages/index.js';
16
18
 
@@ -28,8 +30,12 @@
28
30
  initialSessionId?: string;
29
31
  /** API endpoint configuration */
30
32
  endpointConfig?: EndpointConfig;
33
+ /** Auth provider applied to this instance's API requests. */
34
+ authProvider?: AuthProvider;
31
35
  /** Playground configuration options */
32
36
  config?: PlaygroundConfig;
37
+ /** Per-instance state container — forwarded to the inner Playground */
38
+ instance?: FlowDropInstance;
33
39
  /** Callback when modal is closed */
34
40
  onClose: () => void;
35
41
  }
@@ -40,10 +46,17 @@
40
46
  workflow,
41
47
  initialSessionId,
42
48
  endpointConfig,
49
+ authProvider,
43
50
  config = {},
51
+ instance,
44
52
  onClose
45
53
  }: Props = $props();
46
54
 
55
+ // Unique per component instance so two FlowDrop editors on one page
56
+ // don't render colliding DOM ids (a11y).
57
+ const uid = $props.id();
58
+ const titleId = `${uid}-playground-modal-title`;
59
+
47
60
  /**
48
61
  * Close modal on Escape key
49
62
  */
@@ -71,15 +84,15 @@
71
84
  onkeydown={handleKeydown}
72
85
  role="dialog"
73
86
  aria-modal="true"
74
- aria-labelledby="playground-modal-title"
87
+ aria-labelledby={titleId}
75
88
  tabindex="-1"
76
89
  >
77
90
  <!-- Modal Container -->
78
- <!-- svelte-ignore a11y_no_static_element_interactions a11y_click_events_have_key_events — role="presentation" container stops backdrop click propagation -->
91
+ <!-- role="presentation" container stops backdrop click propagation -->
79
92
  <div class="playground-modal" onclick={(e) => e.stopPropagation()} role="presentation">
80
93
  <!-- Modal Header -->
81
94
  <div class="playground-modal__header">
82
- <div class="playground-modal__title" id="playground-modal-title">
95
+ <div class="playground-modal__title" id={titleId}>
83
96
  <Icon icon="mdi:play-circle-outline" />
84
97
  <span>Playground</span>
85
98
  </div>
@@ -96,11 +109,13 @@
96
109
  <!-- Modal Content -->
97
110
  <div class="playground-modal__content">
98
111
  <Playground
112
+ {instance}
99
113
  {workflowId}
100
114
  {workflow}
101
115
  mode="modal"
102
116
  {initialSessionId}
103
117
  {endpointConfig}
118
+ {authProvider}
104
119
  {config}
105
120
  {onClose}
106
121
  />
@@ -1,5 +1,7 @@
1
1
  import type { Workflow } from '../../types/index.js';
2
+ import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
2
3
  import type { EndpointConfig } from '../../config/endpoints.js';
4
+ import type { AuthProvider } from '../../types/auth.js';
3
5
  import type { PlaygroundConfig } from '../../types/playground.js';
4
6
  /**
5
7
  * Component props
@@ -15,8 +17,12 @@ interface Props {
15
17
  initialSessionId?: string;
16
18
  /** API endpoint configuration */
17
19
  endpointConfig?: EndpointConfig;
20
+ /** Auth provider applied to this instance's API requests. */
21
+ authProvider?: AuthProvider;
18
22
  /** Playground configuration options */
19
23
  config?: PlaygroundConfig;
24
+ /** Per-instance state container — forwarded to the inner Playground */
25
+ instance?: FlowDropInstance;
20
26
  /** Callback when modal is closed */
21
27
  onClose: () => void;
22
28
  }
@@ -3,22 +3,12 @@
3
3
  import Icon from '@iconify/svelte';
4
4
  import Playground from './Playground.svelte';
5
5
  import PipelinePanel from './PipelinePanel.svelte';
6
- import {
7
- getPipelinePanelOpen,
8
- pipelinePanelActions
9
- } from '../../stores/pipelinePanelStore.svelte.js';
10
- import {
11
- getActiveExecutionId,
12
- getPinnedExecutionId,
13
- getLatestExecutionId,
14
- getPipelineRefreshTrigger,
15
- getSelectableExecutions,
16
- playgroundActions
17
- } from '../../stores/playgroundStore.svelte.js';
18
- import { setEndpointConfig, workflowApi } from '../../services/api.js';
6
+ import { provideInstance } from '../../stores/getInstance.svelte.js';
7
+ import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
19
8
  import { logger } from '../../utils/logger.js';
20
9
  import type { Workflow, PipelineViewDef } from '../../types/index.js';
21
10
  import type { EndpointConfig } from '../../config/endpoints.js';
11
+ import type { AuthProvider } from '../../types/auth.js';
22
12
  import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
23
13
 
24
14
  interface Props {
@@ -28,6 +18,8 @@
28
18
  workflow?: Workflow;
29
19
  /** API endpoint configuration */
30
20
  endpointConfig?: EndpointConfig;
21
+ /** Auth provider applied to this instance's API requests. */
22
+ authProvider?: AuthProvider;
31
23
  /** Display mode (default: standalone) */
32
24
  mode?: PlaygroundMode;
33
25
  /** Session ID to activate on mount. Changing this prop remounts the Playground. */
@@ -46,12 +38,15 @@
46
38
  onClose?: () => void;
47
39
  /** Additional pipeline views injected by the consumer */
48
40
  extraPipelineViews?: PipelineViewDef[];
41
+ /** Explicit FlowDrop instance; defaults to context or the page-default instance. */
42
+ instance?: FlowDropInstance;
49
43
  }
50
44
 
51
45
  let {
52
46
  workflowId,
53
47
  workflow: workflowProp,
54
48
  endpointConfig,
49
+ authProvider,
55
50
  mode = 'standalone',
56
51
  initialSessionId,
57
52
  config = {},
@@ -60,17 +55,28 @@
60
55
  initialPipelineWidth = 500,
61
56
  onSessionNavigate,
62
57
  onClose,
63
- extraPipelineViews = []
58
+ extraPipelineViews = [],
59
+ instance
64
60
  }: Props = $props();
65
61
 
66
- // svelte-ignore state_referenced_locally seed mutable state from the prop's initial value; workflow may load asynchronously below
62
+ // Resolve/provide once at init; the instance prop is a fixed mount-time choice.
63
+ // svelte-ignore state_referenced_locally
64
+ const fd = provideInstance(instance);
65
+
66
+ // Pre-bound toggle for detached callback props (onclick / onTogglePanel).
67
+ const togglePipeline = () => fd.pipelinePanel.toggle();
68
+
69
+ // seed mutable state from the prop's initial value; workflow may load asynchronously below
70
+ // svelte-ignore state_referenced_locally
67
71
  let resolvedWorkflow = $state<Workflow | null>(workflowProp ?? null);
68
- // svelte-ignore state_referenced_locally — initial loading flag derived from whether a workflow was provided up front
72
+ // initial loading flag derived from whether a workflow was provided up front
73
+ // svelte-ignore state_referenced_locally
69
74
  let workflowLoading = $state(workflowProp === undefined);
70
75
  let workflowError = $state<string | null>(null);
71
76
 
72
77
  let splitEl = $state<HTMLElement | null>(null);
73
- // svelte-ignore state_referenced_locally — seed mutable width from the initial prop; it changes as the user drags the resizer
78
+ // seed mutable width from the initial prop; it changes as the user drags the resizer
79
+ // svelte-ignore state_referenced_locally
74
80
  let pipelineWidth = $state(initialPipelineWidth);
75
81
  let isResizing = $state(false);
76
82
  let containerWidth = $state(0);
@@ -92,12 +98,12 @@
92
98
  });
93
99
 
94
100
  onMount(() => {
95
- pipelinePanelActions.init();
101
+ fd.pipelinePanel.init();
96
102
  if (initialPipelineOpen !== undefined) {
97
- pipelinePanelActions.setOpen(initialPipelineOpen);
103
+ fd.pipelinePanel.setOpen(initialPipelineOpen);
98
104
  }
99
105
  if (endpointConfig) {
100
- setEndpointConfig(endpointConfig);
106
+ fd.api.configure(endpointConfig, authProvider);
101
107
  }
102
108
  if (!workflowProp) {
103
109
  void loadWorkflow();
@@ -115,7 +121,7 @@
115
121
  try {
116
122
  workflowLoading = true;
117
123
  workflowError = null;
118
- resolvedWorkflow = await workflowApi.getWorkflow(workflowId);
124
+ resolvedWorkflow = await fd.api.client.loadWorkflow(workflowId);
119
125
  } catch (err) {
120
126
  workflowError = err instanceof Error ? err.message : 'Failed to load workflow';
121
127
  logger.error('[PlaygroundStudio] Workflow load failed:', err);
@@ -162,16 +168,16 @@
162
168
  style="--playground-studio-min-chat-width: {minChatWidth}px"
163
169
  >
164
170
  <div class="playground-studio__panes" bind:this={splitEl}>
165
- {#if getPipelinePanelOpen() && resolvedWorkflow && endpointConfig}
166
- {@const activeId = getActiveExecutionId()}
167
- {@const executions = getSelectableExecutions()}
171
+ {#if fd.pipelinePanel.isOpen && resolvedWorkflow && endpointConfig}
172
+ {@const activeId = fd.playground.activeExecutionId}
173
+ {@const executions = fd.playground.selectableExecutions}
168
174
 
169
175
  <div class="playground-studio__pipeline" style="width: {pipelineWidth}px;">
170
176
  <button
171
177
  type="button"
172
178
  class="playground-studio__back-to-chat"
173
179
  aria-label="Back to chat"
174
- onclick={pipelinePanelActions.toggle}
180
+ onclick={togglePipeline}
175
181
  >
176
182
  <Icon icon="mdi:arrow-left" aria-hidden="true" />
177
183
  <span>Back to chat</span>
@@ -180,11 +186,12 @@
180
186
  pipelineId={activeId}
181
187
  workflow={resolvedWorkflow}
182
188
  {endpointConfig}
183
- isPinned={getPinnedExecutionId() !== null}
189
+ {authProvider}
190
+ isPinned={fd.playground.pinnedExecutionId !== null}
184
191
  {executions}
185
- latestExecutionId={getLatestExecutionId()}
186
- onSelectExecution={(id) => playgroundActions.pinExecution(id)}
187
- refreshTrigger={getPipelineRefreshTrigger()}
192
+ latestExecutionId={fd.playground.latestExecutionId}
193
+ onSelectExecution={(id) => fd.playground.pinExecution(id)}
194
+ refreshTrigger={fd.playground.pipelineRefreshTrigger}
188
195
  extraViews={extraPipelineViews}
189
196
  />
190
197
  </div>
@@ -214,7 +221,7 @@
214
221
 
215
222
  <div
216
223
  class="playground-studio__chat"
217
- class:playground-studio__chat--solo={!getPipelinePanelOpen()}
224
+ class:playground-studio__chat--solo={!fd.pipelinePanel.isOpen}
218
225
  >
219
226
  {#if workflowLoading}
220
227
  <div class="playground-studio__loading">
@@ -236,13 +243,14 @@
236
243
  {workflowId}
237
244
  workflow={resolvedWorkflow}
238
245
  {endpointConfig}
246
+ {authProvider}
239
247
  {mode}
240
248
  {initialSessionId}
241
249
  {config}
242
250
  {onClose}
243
251
  {onSessionNavigate}
244
- onTogglePanel={pipelinePanelActions.toggle}
245
- isPipelinePanelOpen={getPipelinePanelOpen()}
252
+ onTogglePanel={togglePipeline}
253
+ isPipelinePanelOpen={fd.pipelinePanel.isOpen}
246
254
  />
247
255
  {/key}
248
256
  {/if}
@@ -1,5 +1,7 @@
1
+ import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
1
2
  import type { Workflow, PipelineViewDef } from '../../types/index.js';
2
3
  import type { EndpointConfig } from '../../config/endpoints.js';
4
+ import type { AuthProvider } from '../../types/auth.js';
3
5
  import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
4
6
  interface Props {
5
7
  /** Target workflow ID */
@@ -8,6 +10,8 @@ interface Props {
8
10
  workflow?: Workflow;
9
11
  /** API endpoint configuration */
10
12
  endpointConfig?: EndpointConfig;
13
+ /** Auth provider applied to this instance's API requests. */
14
+ authProvider?: AuthProvider;
11
15
  /** Display mode (default: standalone) */
12
16
  mode?: PlaygroundMode;
13
17
  /** Session ID to activate on mount. Changing this prop remounts the Playground. */
@@ -26,6 +30,8 @@ interface Props {
26
30
  onClose?: () => void;
27
31
  /** Additional pipeline views injected by the consumer */
28
32
  extraPipelineViews?: PipelineViewDef[];
33
+ /** Explicit FlowDrop instance; defaults to context or the page-default instance. */
34
+ instance?: FlowDropInstance;
29
35
  }
30
36
  declare const PlaygroundStudio: import("svelte").Component<Props, {}, "">;
31
37
  type PlaygroundStudio = ReturnType<typeof PlaygroundStudio>;
@@ -10,14 +10,11 @@
10
10
  import Icon from '@iconify/svelte';
11
11
  import { slide } from 'svelte/transition';
12
12
  import type { PlaygroundSession } from '../../types/playground.js';
13
- import {
14
- getSessions,
15
- getCurrentSession,
16
- getIsLoading,
17
- getSessionCount
18
- } from '../../stores/playgroundStore.svelte.js';
13
+ import { getInstance } from '../../stores/getInstance.svelte.js';
19
14
  import { m } from '../../messages/index.js';
20
15
 
16
+ const fd = getInstance();
17
+
21
18
  /**
22
19
  * Component props
23
20
  */
@@ -175,8 +172,8 @@
175
172
  <div class="session-manager__title">
176
173
  <Icon icon="mdi:history" />
177
174
  <span>{t.header}</span>
178
- {#if getSessionCount() > 0}
179
- <span class="session-manager__count">{getSessionCount()}</span>
175
+ {#if fd.playground.sessionCount > 0}
176
+ <span class="session-manager__count">{fd.playground.sessionCount}</span>
180
177
  {/if}
181
178
  </div>
182
179
  <Icon
@@ -193,7 +190,7 @@
193
190
  type="button"
194
191
  class="session-manager__new-btn"
195
192
  onclick={onCreateSession}
196
- disabled={getIsLoading()}
193
+ disabled={fd.playground.isLoading}
197
194
  >
198
195
  <Icon icon="mdi:plus" />
199
196
  {t.newSession}
@@ -201,16 +198,16 @@
201
198
 
202
199
  <!-- Sessions List -->
203
200
  <div class="session-manager__list">
204
- {#if getSessions().length === 0}
201
+ {#if fd.playground.sessions.length === 0}
205
202
  <div class="session-manager__empty">
206
203
  <Icon icon="mdi:chat-outline" />
207
204
  <span>{t.empty}</span>
208
205
  </div>
209
206
  {:else}
210
- {#each getSessions() as session (session.id)}
207
+ {#each fd.playground.sessions as session (session.id)}
211
208
  <div
212
209
  class="session-manager__item"
213
- class:session-manager__item--active={getCurrentSession()?.id === session.id}
210
+ class:session-manager__item--active={fd.playground.currentSession?.id === session.id}
214
211
  role="button"
215
212
  tabindex="0"
216
213
  onclick={() => handleSelectSession(session.id)}
@@ -1,11 +1,39 @@
1
1
  import type { EndpointConfig } from '../../config/endpoints.js';
2
+ import type { AuthProvider } from '../../types/auth.js';
2
3
  import type { NodeExecutionStatus, KanbanColumnDef } from '../../types/index.js';
3
4
  export type NodeStatus = NodeExecutionStatus;
4
5
  export interface NodeStatusData {
5
6
  status: string;
6
7
  last_executed?: string | null;
7
8
  execution_time?: number | null;
9
+ /** Precise duration in microseconds, from orchestrator-stamped job metadata */
10
+ execution_time_us?: number | null;
8
11
  error?: string | null;
12
+ /** Number of jobs for this node that actually ran (loop iterations) */
13
+ executions?: number | null;
14
+ /** Per-status job counts, e.g. { completed: 2, skipped: 1 } */
15
+ status_counts?: Record<string, number> | null;
16
+ }
17
+ /**
18
+ * One job from the pipeline payload. Loop-orchestrated workflows create one
19
+ * job per iteration for the same node, so a node can have several of these —
20
+ * the label carries the iteration suffix (e.g. "Invoke tool #2").
21
+ */
22
+ export interface PipelineJobItem {
23
+ id: string;
24
+ label: string;
25
+ nodeId: string;
26
+ status: string;
27
+ createdAt?: string | null;
28
+ started?: string | null;
29
+ completed?: string | null;
30
+ /** Precise duration in microseconds, when the job ran to completion */
31
+ executionTimeUs?: number | null;
32
+ error?: string | null;
33
+ retryCount?: number | null;
34
+ maxRetries?: number | null;
35
+ inputData?: unknown;
36
+ outputData?: unknown;
9
37
  }
10
38
  export declare function resolveStatus(raw: NodeStatusData | undefined): NodeStatus;
11
39
  /**
@@ -13,8 +41,9 @@ export declare function resolveStatus(raw: NodeStatusData | undefined): NodeStat
13
41
  * `endpointConfig` is used once to construct the API client — it must be stable.
14
42
  * `getPipelineId` is called on every fetch so pipeline ID changes are picked up.
15
43
  */
16
- export declare function createPipelineDataFetcher(getPipelineId: () => string, endpointConfig: EndpointConfig): {
44
+ export declare function createPipelineDataFetcher(getPipelineId: () => string, endpointConfig: EndpointConfig, authProvider?: AuthProvider): {
17
45
  readonly nodeStatusMap: Record<string, NodeStatusData>;
46
+ readonly jobs: PipelineJobItem[];
18
47
  readonly kanbanConfig: KanbanColumnDef[] | null;
19
48
  readonly isLoading: boolean;
20
49
  readonly isError: boolean;
@@ -11,6 +11,35 @@ const KNOWN_STATUSES = new Set([
11
11
  'failed',
12
12
  'cancelled'
13
13
  ]);
14
+ function toJobItem(raw, index) {
15
+ const started = typeof raw.started === 'string' ? raw.started : null;
16
+ const completed = typeof raw.completed === 'string' ? raw.completed : null;
17
+ // Prefer the orchestrator-stamped microsecond duration; fall back to the
18
+ // second-granularity timestamps for jobs that predate the metadata stamp.
19
+ let executionTimeUs = typeof raw.execution_time_us === 'number' ? raw.execution_time_us : null;
20
+ if (executionTimeUs == null && started && completed) {
21
+ const startMs = Date.parse(started);
22
+ const endMs = Date.parse(completed);
23
+ if (!Number.isNaN(startMs) && !Number.isNaN(endMs)) {
24
+ executionTimeUs = (endMs - startMs) * 1000;
25
+ }
26
+ }
27
+ return {
28
+ id: typeof raw.id === 'string' || typeof raw.id === 'number' ? String(raw.id) : `job-${index}`,
29
+ label: typeof raw.label === 'string' ? raw.label : '',
30
+ nodeId: typeof raw.node_id === 'string' ? raw.node_id : '',
31
+ status: typeof raw.status === 'string' ? raw.status : 'idle',
32
+ createdAt: typeof raw.created_at === 'string' ? raw.created_at : null,
33
+ started,
34
+ completed,
35
+ executionTimeUs,
36
+ error: typeof raw.error_message === 'string' ? raw.error_message : null,
37
+ retryCount: typeof raw.retry_count === 'number' ? raw.retry_count : null,
38
+ maxRetries: typeof raw.max_retries === 'number' ? raw.max_retries : null,
39
+ inputData: raw.input_data ?? null,
40
+ outputData: raw.output_data ?? null
41
+ };
42
+ }
14
43
  export function resolveStatus(raw) {
15
44
  if (!raw)
16
45
  return 'pending';
@@ -26,9 +55,10 @@ export function resolveStatus(raw) {
26
55
  * `endpointConfig` is used once to construct the API client — it must be stable.
27
56
  * `getPipelineId` is called on every fetch so pipeline ID changes are picked up.
28
57
  */
29
- export function createPipelineDataFetcher(getPipelineId, endpointConfig) {
30
- const client = new EnhancedFlowDropApiClient(endpointConfig);
58
+ export function createPipelineDataFetcher(getPipelineId, endpointConfig, authProvider) {
59
+ const client = new EnhancedFlowDropApiClient(endpointConfig, authProvider);
31
60
  let nodeStatusMap = $state({});
61
+ let jobs = $state([]);
32
62
  let kanbanConfig = $state(null);
33
63
  let isLoading = $state(false);
34
64
  let isError = $state(false);
@@ -43,10 +73,14 @@ export function createPipelineDataFetcher(getPipelineId, endpointConfig) {
43
73
  status: info.status,
44
74
  last_executed: info.last_executed,
45
75
  execution_time: info.execution_time,
46
- error: info.error
76
+ execution_time_us: info.execution_time_us,
77
+ error: info.error,
78
+ executions: info.executions,
79
+ status_counts: info.status_counts
47
80
  };
48
81
  }
49
82
  nodeStatusMap = map;
83
+ jobs = (data.jobs ?? []).map(toJobItem);
50
84
  if (data.kanban_config?.columns) {
51
85
  // Server sends statuses as string[]; trust the server and cast at this
52
86
  // boundary. resolveStatus() handles unknown values at read time.
@@ -70,6 +104,9 @@ export function createPipelineDataFetcher(getPipelineId, endpointConfig) {
70
104
  get nodeStatusMap() {
71
105
  return nodeStatusMap;
72
106
  },
107
+ get jobs() {
108
+ return jobs;
109
+ },
73
110
  get kanbanConfig() {
74
111
  return kanbanConfig;
75
112
  },
@@ -3,6 +3,7 @@
3
3
  * Provides configurable endpoints for all API actions
4
4
  */
5
5
  import type { AgentSpecEndpointConfig } from './agentSpecEndpoints.js';
6
+ import type { AuthProvider } from '../types/auth.js';
6
7
  export interface EndpointConfig {
7
8
  /** Base URL for all endpoints */
8
9
  baseUrl: string;
@@ -110,13 +111,6 @@ export interface EndpointConfig {
110
111
  headers?: {
111
112
  [key: string]: Record<string, string>;
112
113
  };
113
- /** Authentication configuration */
114
- auth?: {
115
- type: 'none' | 'bearer' | 'api_key' | 'custom';
116
- token?: string;
117
- apiKey?: string;
118
- headers?: Record<string, string>;
119
- };
120
114
  /** Request timeout in milliseconds */
121
115
  timeout?: number;
122
116
  /** Retry configuration */
@@ -166,3 +160,25 @@ export declare function getEndpointMethod(config: EndpointConfig, endpointKey: s
166
160
  * Get custom headers for an endpoint
167
161
  */
168
162
  export declare function getEndpointHeaders(config: EndpointConfig, endpointKey: string): Record<string, string>;
163
+ /**
164
+ * Build request headers for an endpoint, layering the auth provider's headers
165
+ * over the static endpoint headers.
166
+ *
167
+ * This is the single header-building path shared by the per-instance services
168
+ * (playground, chat, interrupt, settings, port config, categories). Routing all
169
+ * of them through this helper guarantees a configured {@link AuthProvider}
170
+ * authenticates every request consistently — matching the behaviour of
171
+ * {@link EnhancedFlowDropApiClient}, which owns the equivalent merge for the
172
+ * typed workflow/node API.
173
+ *
174
+ * `getAuthHeaders()` is awaited per call so providers can return freshly
175
+ * refreshed tokens. When no provider is supplied the result is identical to
176
+ * {@link getEndpointHeaders} (no auth) — keeping unauthenticated callers
177
+ * working unchanged.
178
+ *
179
+ * @param config - The endpoint configuration
180
+ * @param endpointKey - Key identifying the endpoint (for static header lookup)
181
+ * @param authProvider - Optional auth provider supplying `Authorization` etc.
182
+ * @returns Merged headers: static endpoint headers < auth headers
183
+ */
184
+ export declare function getRequestHeaders(config: EndpointConfig, endpointKey: string, authProvider?: AuthProvider): Promise<Record<string, string>>;
@@ -132,16 +132,8 @@ export function getEndpointHeaders(config, endpointKey) {
132
132
  const baseHeaders = {
133
133
  'Content-Type': 'application/json'
134
134
  };
135
- // Add authentication headers
136
- if (config.auth?.type === 'bearer' && config.auth.token) {
137
- baseHeaders['Authorization'] = `Bearer ${config.auth.token}`;
138
- }
139
- else if (config.auth?.type === 'api_key' && config.auth.apiKey) {
140
- baseHeaders['X-API-Key'] = config.auth.apiKey;
141
- }
142
- else if (config.auth?.type === 'custom' && config.auth.headers) {
143
- Object.assign(baseHeaders, config.auth.headers);
144
- }
135
+ // Authentication is supplied via the AuthProvider passed to the API client /
136
+ // ApiContext EndpointConfig no longer carries an `auth` block.
145
137
  // Add endpoint-specific headers
146
138
  const endpointHeaders = config.headers?.[endpointKey];
147
139
  if (endpointHeaders) {
@@ -149,3 +141,31 @@ export function getEndpointHeaders(config, endpointKey) {
149
141
  }
150
142
  return baseHeaders;
151
143
  }
144
+ /**
145
+ * Build request headers for an endpoint, layering the auth provider's headers
146
+ * over the static endpoint headers.
147
+ *
148
+ * This is the single header-building path shared by the per-instance services
149
+ * (playground, chat, interrupt, settings, port config, categories). Routing all
150
+ * of them through this helper guarantees a configured {@link AuthProvider}
151
+ * authenticates every request consistently — matching the behaviour of
152
+ * {@link EnhancedFlowDropApiClient}, which owns the equivalent merge for the
153
+ * typed workflow/node API.
154
+ *
155
+ * `getAuthHeaders()` is awaited per call so providers can return freshly
156
+ * refreshed tokens. When no provider is supplied the result is identical to
157
+ * {@link getEndpointHeaders} (no auth) — keeping unauthenticated callers
158
+ * working unchanged.
159
+ *
160
+ * @param config - The endpoint configuration
161
+ * @param endpointKey - Key identifying the endpoint (for static header lookup)
162
+ * @param authProvider - Optional auth provider supplying `Authorization` etc.
163
+ * @returns Merged headers: static endpoint headers < auth headers
164
+ */
165
+ export async function getRequestHeaders(config, endpointKey, authProvider) {
166
+ const headers = getEndpointHeaders(config, endpointKey);
167
+ if (authProvider) {
168
+ Object.assign(headers, await authProvider.getAuthHeaders());
169
+ }
170
+ return headers;
171
+ }
@@ -22,12 +22,12 @@ export type { WorkflowEditorConfig, EditorFeatures, UIConfig, APIConfig, Executi
22
22
  export type { AuthProvider, StaticAuthConfig, CallbackAuthConfig } from '../types/auth.js';
23
23
  export type { WorkflowChangeType, FlowDropEventHandlers, FlowDropFeatures } from '../types/events.js';
24
24
  export type { FieldSchema, FieldType, FieldFormat, FieldOption, SchemaFormProps, BaseFieldProps, TextFieldProps, TextareaFieldProps, NumberFieldProps, ToggleFieldProps, RangeFieldProps, SelectFieldProps, CheckboxGroupFieldProps, ArrayFieldProps, CodeEditorFieldProps, MarkdownEditorFieldProps, TemplateEditorFieldProps, FormFieldFactoryProps, FormFieldWrapperProps } from '../components/form/types.js';
25
- export { BaseRegistry } from '../registry/BaseRegistry.js';
25
+ export { BaseRegistry } from '../registry/BaseRegistry.svelte.js';
26
26
  export type { NodeComponentProps, NodeTypeInfo, NodeComponentRegistration, NodeComponentCategory, StatusPosition, StatusSize, NodeRegistrationFilter, FlowDropPluginConfig, PluginNodeDefinition, PluginRegistrationResult } from '../registry/index.js';
27
27
  export type { FieldMatcherRegistration } from '../form/fieldRegistry.js';
28
- export { workflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
28
+ export { WorkflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
29
29
  export type { WorkflowFormatAdapter, FormatValidationResult } from '../registry/workflowFormatRegistry.js';
30
- export { registerBuiltinFormats, areBuiltinFormatsRegistered, resetBuiltinFormatRegistration } from '../registry/builtinFormats.js';
30
+ export { getBuiltinFormatAdapters } from '../registry/builtinFormats.js';
31
31
  export type { ToastType, ToastOptions } from '../services/toastService.js';
32
32
  export type { DynamicSchemaResult } from '../services/dynamicSchemaService.js';
33
33
  export type { PlaygroundSession, PlaygroundMessage, PlaygroundInputField, PlaygroundMessageRequest, PlaygroundMessagesResult, PlaygroundConfig, PlaygroundMode, PlaygroundSessionStatus, PlaygroundMessageRole, PlaygroundMessageLevel, PlaygroundMessageMetadata, PlaygroundApiResponse, PlaygroundSessionsResponse, PlaygroundSessionResponse, PlaygroundMessageResponse, PlaygroundMessagesApiResponse } from '../types/playground.js';
@@ -68,16 +68,15 @@ export { computeAutoLayout } from '../adapters/agentspec/autoLayout.js';
68
68
  export type { AutoLayoutConfig } from '../adapters/agentspec/autoLayout.js';
69
69
  export type { AgentSpecEndpointConfig } from '../config/agentSpecEndpoints.js';
70
70
  export { defaultAgentSpecEndpoints, createAgentSpecEndpointConfig, buildAgentSpecUrl, getAgentSpecAuthHeaders } from '../config/agentSpecEndpoints.js';
71
- export { AgentSpecExecutionService, agentSpecExecutionService } from '../services/agentSpecExecutionService.js';
71
+ export { AgentSpecExecutionService } from '../services/agentSpecExecutionService.js';
72
72
  export type { AgentSpecExecutionHandle } from '../services/agentSpecExecutionService.js';
73
- export { workflowSchema, WORKFLOW_SCHEMA_VERSION } from '../schema/index.js';
73
+ export { workflowSchema, WORKFLOW_SCHEMA_VERSION } from '../schemas/index.js';
74
74
  export type { FlowDropTheme, FlowDropThemeName, FlowDropThemeConfig } from '../types/theme.js';
75
75
  export { defaultTheme, minimalTheme, resolveTheme } from '../themes/index.js';
76
76
  export type { FlowDropSkin, FlowDropSkinName, FlowDropSkinTokens } from '../types/skin.js';
77
77
  export { slateSkin, defaultSkin } from '../skins/index.js';
78
78
  export type { ThemePreference, ResolvedTheme } from '../stores/settingsStore.svelte.js';
79
79
  export { getTheme as theme, getResolvedTheme as resolvedTheme, setTheme, toggleTheme, cycleTheme, initializeTheme, isThemeInitialized } from '../stores/settingsStore.svelte.js';
80
- export { sanitizeHtml } from '../utils/sanitize.js';
81
80
  export { logger, setLogLevel, getLogLevel } from '../utils/logger.js';
82
81
  export type { LogLevel } from '../utils/logger.js';
83
82
  export { computeSwapPreview, computeSwapPreviewWithOptions, executeSwap, mapConfig, getVersionUpgrade, compareSemver, performSwap, validateSwapResult, SwapValidationError } from '../utils/nodeSwap.js';
@@ -17,11 +17,11 @@
17
17
  export { DEFAULT_WORKFLOW_FORMAT } from '../types/index.js';
18
18
  export { isUISchemaControl, isUISchemaVerticalLayout, isUISchemaGroup } from '../types/index.js';
19
19
  // Base registry
20
- export { BaseRegistry } from '../registry/BaseRegistry.js';
21
- // Workflow format registry
22
- export { workflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
23
- // Built-in format registration helpers
24
- export { registerBuiltinFormats, areBuiltinFormatsRegistered, resetBuiltinFormatRegistration } from '../registry/builtinFormats.js';
20
+ export { BaseRegistry } from '../registry/BaseRegistry.svelte.js';
21
+ // Workflow format registry (the class — instances live on `fd.formats`)
22
+ export { WorkflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
23
+ // Built-in format adapters (used to seed instance format registries)
24
+ export { getBuiltinFormatAdapters } from '../registry/builtinFormats.js';
25
25
  export { isChatInputNode, CHAT_INPUT_PATTERNS } from '../types/playground.js';
26
26
  // ============================================================================
27
27
  // Authentication Providers (no dependencies)
@@ -80,20 +80,16 @@ export { validateForAgentSpecExport, validateAgentSpecFlow } from '../adapters/a
80
80
  // Agent Spec auto-layout
81
81
  export { computeAutoLayout } from '../adapters/agentspec/autoLayout.js';
82
82
  export { defaultAgentSpecEndpoints, createAgentSpecEndpointConfig, buildAgentSpecUrl, getAgentSpecAuthHeaders } from '../config/agentSpecEndpoints.js';
83
- // Agent Spec execution service
84
- export { AgentSpecExecutionService, agentSpecExecutionService } from '../services/agentSpecExecutionService.js';
83
+ // Agent Spec execution service (instantiate per instance — no global singleton)
84
+ export { AgentSpecExecutionService } from '../services/agentSpecExecutionService.js';
85
85
  // ============================================================================
86
86
  // Workflow JSON Schema
87
87
  // ============================================================================
88
- export { workflowSchema, WORKFLOW_SCHEMA_VERSION } from '../schema/index.js';
88
+ export { workflowSchema, WORKFLOW_SCHEMA_VERSION } from '../schemas/index.js';
89
89
  export { defaultTheme, minimalTheme, resolveTheme } from '../themes/index.js';
90
90
  export { slateSkin, defaultSkin } from '../skins/index.js';
91
91
  export { getTheme as theme, getResolvedTheme as resolvedTheme, setTheme, toggleTheme, cycleTheme, initializeTheme, isThemeInitialized } from '../stores/settingsStore.svelte.js';
92
92
  // ============================================================================
93
- // HTML Sanitization
94
- // ============================================================================
95
- export { sanitizeHtml } from '../utils/sanitize.js';
96
- // ============================================================================
97
93
  // Logger
98
94
  // ============================================================================
99
95
  export { logger, setLogLevel, getLogLevel } from '../utils/logger.js';