@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
@@ -23,6 +23,12 @@ interface AutoSaveOptions {
23
23
  * Optional callback for successful saves
24
24
  */
25
25
  onSuccess?: () => void;
26
+ /**
27
+ * Dirty-state probe for the owning FlowDrop instance, e.g.
28
+ * `() => fd.workflow.isDirty`. Defaults to the page-default
29
+ * instance's dirty state when omitted.
30
+ */
31
+ isDirty?: () => boolean;
26
32
  }
27
33
  /**
28
34
  * Initialize auto-save functionality based on user settings
@@ -68,6 +74,7 @@ export declare class AutoSaveManager {
68
74
  private onSave;
69
75
  private onError?;
70
76
  private onSuccess?;
77
+ private isDirtyProbe;
71
78
  /**
72
79
  * Create a new AutoSaveManager
73
80
  *
@@ -7,7 +7,7 @@
7
7
  * @module services/autoSaveService
8
8
  */
9
9
  import { getBehaviorSettings, onSettingsChange } from '../stores/settingsStore.svelte.js';
10
- import { isDirty } from '../stores/workflowStore.svelte.js';
10
+ import { getDefaultInstance } from '../stores/instanceContainer.svelte.js';
11
11
  import { logger } from '../utils/logger.js';
12
12
  /**
13
13
  * Initialize auto-save functionality based on user settings
@@ -40,7 +40,7 @@ import { logger } from '../utils/logger.js';
40
40
  * ```
41
41
  */
42
42
  export function initAutoSave(options) {
43
- const { onSave, onError, onSuccess } = options;
43
+ const { onSave, onError, onSuccess, isDirty: isDirtyProbe = () => getDefaultInstance().workflow.isDirty } = options;
44
44
  const state = {
45
45
  intervalId: null,
46
46
  isSaving: false,
@@ -52,7 +52,7 @@ export function initAutoSave(options) {
52
52
  */
53
53
  async function performAutoSave() {
54
54
  // Skip if already saving or not dirty
55
- if (state.isSaving || !isDirty()) {
55
+ if (state.isSaving || !isDirtyProbe()) {
56
56
  return;
57
57
  }
58
58
  state.isSaving = true;
@@ -127,6 +127,7 @@ export class AutoSaveManager {
127
127
  onSave;
128
128
  onError;
129
129
  onSuccess;
130
+ isDirtyProbe;
130
131
  /**
131
132
  * Create a new AutoSaveManager
132
133
  *
@@ -136,6 +137,7 @@ export class AutoSaveManager {
136
137
  this.onSave = options.onSave;
137
138
  this.onError = options.onError;
138
139
  this.onSuccess = options.onSuccess;
140
+ this.isDirtyProbe = options.isDirty ?? (() => getDefaultInstance().workflow.isDirty);
139
141
  }
140
142
  /**
141
143
  * Start the auto-save manager
@@ -207,7 +209,7 @@ export class AutoSaveManager {
207
209
  * Perform the save operation
208
210
  */
209
211
  async performSave() {
210
- if (this.isSaving || !isDirty()) {
212
+ if (this.isSaving || !this.isDirtyProbe()) {
211
213
  return;
212
214
  }
213
215
  this.isSaving = true;
@@ -2,7 +2,8 @@
2
2
  * Categories API Service
3
3
  * Handles fetching category definitions from the backend
4
4
  */
5
- import { buildEndpointUrl, getEndpointHeaders } from '../config/endpoints.js';
5
+ import { buildEndpointUrl } from '../config/endpoints.js';
6
+ import { authenticatedFetch } from '../utils/fetchWithAuth.js';
6
7
  import { DEFAULT_CATEGORIES } from '../config/defaultCategories.js';
7
8
  import { logger } from '../utils/logger.js';
8
9
  /**
@@ -11,11 +12,7 @@ import { logger } from '../utils/logger.js';
11
12
  export async function fetchCategories(endpointConfig, authProvider) {
12
13
  try {
13
14
  const url = buildEndpointUrl(endpointConfig, endpointConfig.endpoints.categories);
14
- const configHeaders = getEndpointHeaders(endpointConfig, 'categories');
15
- const authHeaders = authProvider ? await authProvider.getAuthHeaders() : {};
16
- const response = await fetch(url, {
17
- headers: { ...configHeaders, ...authHeaders }
18
- });
15
+ const response = await authenticatedFetch(url, {}, { config: endpointConfig, endpointKey: 'categories', authProvider });
19
16
  if (!response.ok) {
20
17
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
21
18
  }
@@ -7,6 +7,8 @@
7
7
  * @module services/chatService
8
8
  */
9
9
  import type { ChatRequest, ChatResponse, ChatHistoryMessage } from '../types/chat.js';
10
+ import type { EndpointConfig } from '../config/endpoints.js';
11
+ import type { AuthProvider } from '../types/auth.js';
10
12
  /**
11
13
  * Chat Service class
12
14
  *
@@ -23,7 +25,9 @@ export declare class ChatService {
23
25
  */
24
26
  static getInstance(): ChatService;
25
27
  /**
26
- * Get the endpoint configuration
28
+ * Validate and return the caller-supplied endpoint configuration.
29
+ *
30
+ * Callers thread the config from `getInstance().api.config`.
27
31
  *
28
32
  * @throws Error if endpoint configuration is not set
29
33
  * @returns The endpoint configuration
@@ -32,6 +36,7 @@ export declare class ChatService {
32
36
  /**
33
37
  * Generic API request helper
34
38
  *
39
+ * @param config - The endpoint configuration
35
40
  * @param url - The URL to fetch
36
41
  * @param options - Fetch options
37
42
  * @returns The parsed JSON response
@@ -44,20 +49,20 @@ export declare class ChatService {
44
49
  * @param request - The chat request payload
45
50
  * @returns The chat response from the LLM
46
51
  */
47
- sendMessage(workflowId: string, request: ChatRequest): Promise<ChatResponse>;
52
+ sendMessage(endpointConfig: EndpointConfig | null, workflowId: string, request: ChatRequest, authProvider?: AuthProvider): Promise<ChatResponse>;
48
53
  /**
49
54
  * Get conversation history for a workflow
50
55
  *
51
56
  * @param workflowId - The workflow ID
52
57
  * @returns Array of chat history messages
53
58
  */
54
- getHistory(workflowId: string): Promise<ChatHistoryMessage[]>;
59
+ getHistory(endpointConfig: EndpointConfig | null, workflowId: string, authProvider?: AuthProvider): Promise<ChatHistoryMessage[]>;
55
60
  /**
56
61
  * Clear conversation history for a workflow
57
62
  *
58
63
  * @param workflowId - The workflow ID
59
64
  */
60
- clearHistory(workflowId: string): Promise<void>;
65
+ clearHistory(endpointConfig: EndpointConfig | null, workflowId: string, authProvider?: AuthProvider): Promise<void>;
61
66
  }
62
67
  /**
63
68
  * Pre-instantiated ChatService singleton
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * @module services/chatService
8
8
  */
9
- import { buildEndpointUrl, getEndpointHeaders } from '../config/endpoints.js';
10
- import { getEndpointConfig } from './api.js';
9
+ import { buildEndpointUrl } from '../config/endpoints.js';
10
+ import { authenticatedFetch } from '../utils/fetchWithAuth.js';
11
11
  import { logger } from '../utils/logger.js';
12
12
  /**
13
13
  * Chat Service class
@@ -30,34 +30,32 @@ export class ChatService {
30
30
  return ChatService.instance;
31
31
  }
32
32
  /**
33
- * Get the endpoint configuration
33
+ * Validate and return the caller-supplied endpoint configuration.
34
+ *
35
+ * Callers thread the config from `getInstance().api.config`.
34
36
  *
35
37
  * @throws Error if endpoint configuration is not set
36
38
  * @returns The endpoint configuration
37
39
  */
38
- getConfig() {
39
- const config = getEndpointConfig();
40
+ getConfig(config) {
40
41
  if (!config) {
41
- throw new Error('Endpoint configuration not set. Call setEndpointConfig() first.');
42
+ throw new Error('Endpoint configuration not set. Configure the instance via fd.api.configure().');
42
43
  }
43
44
  return config;
44
45
  }
45
46
  /**
46
47
  * Generic API request helper
47
48
  *
49
+ * @param config - The endpoint configuration
48
50
  * @param url - The URL to fetch
49
51
  * @param options - Fetch options
50
52
  * @returns The parsed JSON response
51
53
  */
52
- async request(url, options = {}) {
53
- const config = this.getConfig();
54
- const headers = getEndpointHeaders(config, 'chat');
55
- const response = await fetch(url, {
56
- ...options,
57
- headers: {
58
- ...headers,
59
- ...options.headers
60
- }
54
+ async request(config, url, options = {}, authProvider) {
55
+ const response = await authenticatedFetch(url, options, {
56
+ config,
57
+ endpointKey: 'chat',
58
+ authProvider
61
59
  });
62
60
  if (!response.ok) {
63
61
  const errorData = await response.json().catch(() => ({}));
@@ -83,16 +81,16 @@ export class ChatService {
83
81
  * @param request - The chat request payload
84
82
  * @returns The chat response from the LLM
85
83
  */
86
- async sendMessage(workflowId, request) {
87
- const config = this.getConfig();
84
+ async sendMessage(endpointConfig, workflowId, request, authProvider) {
85
+ const config = this.getConfig(endpointConfig);
88
86
  const url = buildEndpointUrl(config, config.endpoints.chat.sendMessage, {
89
87
  id: workflowId
90
88
  });
91
89
  logger.debug('[ChatService] Sending message to', url);
92
- return this.request(url, {
90
+ return this.request(config, url, {
93
91
  method: 'POST',
94
92
  body: JSON.stringify(request)
95
- });
93
+ }, authProvider);
96
94
  }
97
95
  /**
98
96
  * Get conversation history for a workflow
@@ -100,29 +98,26 @@ export class ChatService {
100
98
  * @param workflowId - The workflow ID
101
99
  * @returns Array of chat history messages
102
100
  */
103
- async getHistory(workflowId) {
104
- const config = this.getConfig();
101
+ async getHistory(endpointConfig, workflowId, authProvider) {
102
+ const config = this.getConfig(endpointConfig);
105
103
  const url = buildEndpointUrl(config, config.endpoints.chat.getHistory, {
106
104
  id: workflowId
107
105
  });
108
106
  logger.debug('[ChatService] Getting history from', url);
109
- return this.request(url);
107
+ return this.request(config, url, {}, authProvider);
110
108
  }
111
109
  /**
112
110
  * Clear conversation history for a workflow
113
111
  *
114
112
  * @param workflowId - The workflow ID
115
113
  */
116
- async clearHistory(workflowId) {
117
- const config = this.getConfig();
114
+ async clearHistory(endpointConfig, workflowId, authProvider) {
115
+ const config = this.getConfig(endpointConfig);
118
116
  const url = buildEndpointUrl(config, config.endpoints.chat.clearHistory, {
119
117
  id: workflowId
120
118
  });
121
119
  logger.debug('[ChatService] Clearing history at', url);
122
- await fetch(url, {
123
- method: 'DELETE',
124
- headers: getEndpointHeaders(config, 'chat')
125
- });
120
+ await authenticatedFetch(url, { method: 'DELETE' }, { config, endpointKey: 'chat', authProvider });
126
121
  }
127
122
  }
128
123
  /**
@@ -1,12 +1,82 @@
1
1
  /**
2
2
  * Draft Storage Service for FlowDrop
3
3
  *
4
- * Handles saving and loading workflow drafts to/from localStorage.
4
+ * Handles saving and loading workflow drafts to/from browser storage
5
+ * (localStorage by default, configurable via {@link setDraftStorage}).
5
6
  * Provides interval-based auto-save functionality.
6
7
  *
7
8
  * @module services/draftStorage
8
9
  */
9
10
  import type { Workflow } from '../types/index.js';
11
+ /**
12
+ * Minimal storage adapter used for draft persistence.
13
+ *
14
+ * Implement this to back drafts with anything other than the built-in
15
+ * `localStorage` / `sessionStorage` options — e.g. an in-memory store, a
16
+ * key-prefixed wrapper, or a synchronous write-through cache.
17
+ *
18
+ * Note the interface is deliberately **synchronous**. Async backends
19
+ * (IndexedDB, network storage, WebCrypto-encrypted stores) cannot implement
20
+ * it directly — put a synchronous in-memory cache in front and flush to the
21
+ * async backend out of band. An `async` method assigned here will type-check
22
+ * (a Promise is assignable to `void`) but its errors are silently swallowed.
23
+ */
24
+ export interface DraftStorageAdapter {
25
+ /** Read a value, or null when absent */
26
+ getItem(key: string): string | null;
27
+ /** Write a value */
28
+ setItem(key: string, value: string): void;
29
+ /** Remove a value */
30
+ removeItem(key: string): void;
31
+ /** List all keys currently held by the adapter */
32
+ keys(): string[];
33
+ }
34
+ /**
35
+ * Built-in storage backends
36
+ * - 'local': localStorage — drafts persist on the device even after the tab
37
+ * or browser is closed, until saved or cleared
38
+ * - 'session': sessionStorage — drafts are scoped to the tab and removed
39
+ * when it closes (they do not survive crash-and-reopen)
40
+ */
41
+ export type DraftStorageType = 'local' | 'session';
42
+ /** Accepted values for the `draftStorage` mount option */
43
+ export type DraftStorageOption = DraftStorageType | DraftStorageAdapter;
44
+ /**
45
+ * Resolve a {@link DraftStorageOption} to a concrete adapter.
46
+ *
47
+ * `'local'` / `'session'` map to the built-in Web Storage adapters, a custom
48
+ * adapter is returned as-is, and `undefined` resolves to the current
49
+ * module-level default (see {@link setDraftStorage}).
50
+ */
51
+ export declare function resolveDraftStorage(option?: DraftStorageOption): DraftStorageAdapter;
52
+ /**
53
+ * Configure the module-level default for where workflow drafts are persisted.
54
+ *
55
+ * - `'local'` (default): `localStorage` — drafts survive reloads and browser
56
+ * restarts, and remain stored on the device even after the tab is closed,
57
+ * until saved or cleared.
58
+ * - `'session'`: `sessionStorage` — drafts are scoped to the current tab and
59
+ * removed when it closes. Note this also means drafts do not survive a
60
+ * crash-and-reopen.
61
+ * - A custom {@link DraftStorageAdapter} for anything else.
62
+ *
63
+ * This sets the default used by the standalone helpers and by managers
64
+ * constructed without an explicit `storage` option. Mounted apps capture
65
+ * their own adapter at mount time, so calling this does not retarget
66
+ * already-running instances. With multiple mounts the most recent mount's
67
+ * backend wins *for the standalone helpers only*.
68
+ *
69
+ * Security note: neither built-in backend protects against same-origin
70
+ * script access (XSS) — both are readable by any script on the page. If
71
+ * workflows may contain secrets in node configs, disable drafts via
72
+ * `features.autoSaveDraft: false` or keep them off-disk with a custom
73
+ * in-memory adapter.
74
+ */
75
+ export declare function setDraftStorage(option: DraftStorageOption): void;
76
+ /**
77
+ * Get the current module-level default draft storage adapter
78
+ */
79
+ export declare function getDraftStorage(): DraftStorageAdapter;
10
80
  /**
11
81
  * Draft metadata stored alongside the workflow
12
82
  */
@@ -19,7 +89,7 @@ interface DraftMetadata {
19
89
  workflowName?: string;
20
90
  }
21
91
  /**
22
- * Complete draft data stored in localStorage
92
+ * Complete draft data stored in draft storage
23
93
  */
24
94
  interface StoredDraft {
25
95
  /** The workflow data */
@@ -27,6 +97,14 @@ interface StoredDraft {
27
97
  /** Draft metadata */
28
98
  metadata: DraftMetadata;
29
99
  }
100
+ /**
101
+ * Storage prefix of the page-default instance (`flowdrop:draft:default`).
102
+ *
103
+ * Every instance — including the default — uses an id-scoped prefix since
104
+ * v2.0. Standalone helper callers that don't pass a prefix get this one, so
105
+ * they keep addressing the default editor's drafts.
106
+ */
107
+ export declare const DEFAULT_INSTANCE_DRAFT_PREFIX = "flowdrop:draft:default";
30
108
  /**
31
109
  * Generate a storage key for a workflow
32
110
  *
@@ -35,48 +113,70 @@ interface StoredDraft {
35
113
  *
36
114
  * @param workflowId - The workflow ID (optional)
37
115
  * @param customKey - Custom storage key provided by enterprise (optional)
116
+ * @param prefix - Key namespace; pass a FlowDrop instance's `storagePrefix`
117
+ * to scope drafts per instance. Defaults to the page-default instance's
118
+ * prefix.
38
119
  * @returns The storage key to use
39
120
  */
40
- export declare function getDraftStorageKey(workflowId?: string, customKey?: string): string;
121
+ export declare function getDraftStorageKey(workflowId?: string, customKey?: string, prefix?: string): string;
122
+ /**
123
+ * One-time migration of a 1.x draft key to its 2.0 scoped equivalent.
124
+ *
125
+ * In 1.x the page-default instance stored drafts under the bare
126
+ * `flowdrop:draft:<workflowId>` key; since 2.0 it uses
127
+ * `flowdrop:draft:default:<workflowId>`. When the scoped key is empty and the
128
+ * legacy key holds a draft, the draft is moved (copied, then the legacy key
129
+ * removed) so users upgrading mid-edit don't lose work.
130
+ *
131
+ * @param legacyKey - The 1.x bare-prefix key
132
+ * @param scopedKey - The 2.0 instance-scoped key
133
+ * @param storage - Adapter to migrate within (defaults to the module-level default)
134
+ */
135
+ export declare function migrateLegacyDraftKey(legacyKey: string, scopedKey: string, storage?: DraftStorageAdapter): void;
41
136
  /**
42
- * Save a workflow draft to localStorage
137
+ * Save a workflow draft to draft storage
43
138
  *
44
139
  * @param workflow - The workflow to save
45
140
  * @param storageKey - The storage key to use
141
+ * @param storage - Adapter to write to (defaults to the module-level default)
46
142
  * @returns true if saved successfully, false otherwise
47
143
  */
48
- export declare function saveDraft(workflow: Workflow, storageKey: string): boolean;
144
+ export declare function saveDraft(workflow: Workflow, storageKey: string, storage?: DraftStorageAdapter): boolean;
49
145
  /**
50
- * Load a workflow draft from localStorage
146
+ * Load a workflow draft from draft storage
51
147
  *
52
148
  * @param storageKey - The storage key to load from
149
+ * @param storage - Adapter to read from (defaults to the module-level default)
53
150
  * @returns The stored draft, or null if not found
54
151
  */
55
- export declare function loadDraft(storageKey: string): StoredDraft | null;
152
+ export declare function loadDraft(storageKey: string, storage?: DraftStorageAdapter): StoredDraft | null;
56
153
  /**
57
- * Delete a workflow draft from localStorage
154
+ * Delete a workflow draft from draft storage
58
155
  *
59
156
  * @param storageKey - The storage key to delete
157
+ * @param storage - Adapter to delete from (defaults to the module-level default)
60
158
  */
61
- export declare function deleteDraft(storageKey: string): void;
159
+ export declare function deleteDraft(storageKey: string, storage?: DraftStorageAdapter): void;
62
160
  /**
63
161
  * Check if a draft exists for a given storage key
64
162
  *
65
163
  * @param storageKey - The storage key to check
164
+ * @param storage - Adapter to check (defaults to the module-level default)
66
165
  * @returns true if a draft exists
67
166
  */
68
- export declare function hasDraft(storageKey: string): boolean;
167
+ export declare function hasDraft(storageKey: string, storage?: DraftStorageAdapter): boolean;
69
168
  /**
70
169
  * Get draft metadata without loading the full workflow
71
170
  *
72
171
  * Useful for displaying draft information without parsing the entire workflow.
73
172
  *
74
173
  * @param storageKey - The storage key to check
174
+ * @param storage - Adapter to read from (defaults to the module-level default)
75
175
  * @returns Draft metadata, or null if not found
76
176
  */
77
- export declare function getDraftMetadata(storageKey: string): DraftMetadata | null;
177
+ export declare function getDraftMetadata(storageKey: string, storage?: DraftStorageAdapter): DraftMetadata | null;
78
178
  /**
79
- * Clear all FlowDrop drafts from localStorage
179
+ * Clear all FlowDrop drafts from draft storage
80
180
  *
81
181
  * Removes every key beginning with `flowdrop:draft:`. Intended to be called
82
182
  * from a host application's logout handler so workflow drafts do not persist
@@ -85,9 +185,10 @@ export declare function getDraftMetadata(storageKey: string): DraftMetadata | nu
85
185
  * @param extraKeys - Additional explicit keys to remove. Pass any custom
86
186
  * `draftStorageKey` values configured at mount time so they are cleared
87
187
  * alongside the default-prefixed keys.
188
+ * @param storage - Adapter to clear (defaults to the module-level default)
88
189
  * @returns The number of entries removed.
89
190
  */
90
- export declare function clearAllDrafts(extraKeys?: readonly string[]): number;
191
+ export declare function clearAllDrafts(extraKeys?: readonly string[], storage?: DraftStorageAdapter): number;
91
192
  /**
92
193
  * Draft auto-save manager
93
194
  *
@@ -107,6 +208,17 @@ export declare class DraftAutoSaveManager {
107
208
  private getWorkflow;
108
209
  /** Function to check if workflow is dirty */
109
210
  private isDirty;
211
+ /**
212
+ * Runtime gate for draft persistence (e.g. a user-facing opt-out setting).
213
+ * Checked on every save, so it can change after construction.
214
+ */
215
+ private isPersistenceAllowed;
216
+ /**
217
+ * Storage adapter this instance writes to.
218
+ * Captured at construction, so a later `setDraftStorage()` call (e.g. from
219
+ * another FlowDrop mount on the same page) cannot retarget this manager.
220
+ */
221
+ private storage;
110
222
  /** Last saved workflow hash (for change detection) */
111
223
  private lastSavedHash;
112
224
  /**
@@ -120,6 +232,10 @@ export declare class DraftAutoSaveManager {
120
232
  enabled: boolean;
121
233
  getWorkflow: () => Workflow | null;
122
234
  isDirty: () => boolean;
235
+ /** Optional runtime gate — return false to suppress draft writes (default: always allowed) */
236
+ isPersistenceAllowed?: () => boolean;
237
+ /** Storage backend for this instance (default: the module-level default at construction time) */
238
+ storage?: DraftStorageOption;
123
239
  });
124
240
  /**
125
241
  * Start auto-save interval