@flowdrop/flowdrop 1.15.0 → 2.0.0-beta.1

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 (215) hide show
  1. package/CHANGELOG.md +475 -0
  2. package/MIGRATION-2.0.md +472 -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/chat/batchFeedback.d.ts +39 -0
  8. package/dist/chat/batchFeedback.js +51 -0
  9. package/dist/commands/executor.js +15 -1
  10. package/dist/commands/storeIntegration.svelte.d.ts +4 -1
  11. package/dist/commands/storeIntegration.svelte.js +26 -21
  12. package/dist/commands/types.d.ts +2 -0
  13. package/dist/components/App.svelte +162 -192
  14. package/dist/components/App.svelte.d.ts +47 -8
  15. package/dist/components/ConfigForm.svelte +71 -47
  16. package/dist/components/ConfigModal.svelte +7 -2
  17. package/dist/components/ConnectionLine.svelte +4 -2
  18. package/dist/components/Navbar.svelte +61 -1
  19. package/dist/components/NodeSidebar.svelte +27 -45
  20. package/dist/components/NodeStatusOverlay.svelte +94 -6
  21. package/dist/components/NodeSwapPicker.svelte +10 -8
  22. package/dist/components/PipelineStatus.svelte +16 -67
  23. package/dist/components/PortCoordinateTracker.svelte +5 -6
  24. package/dist/components/SchemaForm.stories.svelte +1 -3
  25. package/dist/components/SchemaForm.svelte +18 -25
  26. package/dist/components/SchemaForm.svelte.d.ts +0 -8
  27. package/dist/components/SettingsModal.svelte +8 -3
  28. package/dist/components/SettingsPanel.svelte +20 -4
  29. package/dist/components/SwapMappingEditor.svelte +67 -49
  30. package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
  31. package/dist/components/UniversalNode.svelte +9 -7
  32. package/dist/components/WorkflowEditor.svelte +118 -111
  33. package/dist/components/WorkflowEditor.svelte.d.ts +18 -10
  34. package/dist/components/chat/AIChatPanel.svelte +93 -89
  35. package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
  36. package/dist/components/chat/CommandPreview.svelte +2 -1
  37. package/dist/components/console/CommandConsole.svelte +7 -5
  38. package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
  39. package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
  40. package/dist/components/console/ConsoleInput.svelte +15 -6
  41. package/dist/components/console/ConsoleOutput.svelte +2 -1
  42. package/dist/components/form/FormArray.svelte +5 -9
  43. package/dist/components/form/FormArray.svelte.d.ts +2 -1
  44. package/dist/components/form/FormAutocomplete.svelte +8 -6
  45. package/dist/components/form/FormField.svelte +4 -2
  46. package/dist/components/form/FormFieldLight.svelte +4 -2
  47. package/dist/components/form/FormMarkdownEditor.svelte +9 -4
  48. package/dist/components/form/FormRangeField.svelte +1 -0
  49. package/dist/components/form/FormTemplateEditor.svelte +11 -3
  50. package/dist/components/form/FormToggle.svelte +5 -12
  51. package/dist/components/form/FormToggle.svelte.d.ts +4 -2
  52. package/dist/components/form/templateAutocomplete.js +1 -5
  53. package/dist/components/form/types.d.ts +1 -14
  54. package/dist/components/interrupt/FormPrompt.svelte +3 -2
  55. package/dist/components/interrupt/InterruptBubble.svelte +16 -17
  56. package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
  57. package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
  58. package/dist/components/layouts/MainLayout.svelte +20 -13
  59. package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
  60. package/dist/components/nodes/AtomNode.svelte +17 -5
  61. package/dist/components/nodes/GatewayNode.svelte +19 -10
  62. package/dist/components/nodes/IdeaNode.svelte +7 -0
  63. package/dist/components/nodes/SimpleNode.svelte +11 -6
  64. package/dist/components/nodes/SquareNode.svelte +15 -8
  65. package/dist/components/nodes/TerminalNode.svelte +9 -4
  66. package/dist/components/nodes/ToolNode.svelte +7 -1
  67. package/dist/components/nodes/WorkflowNode.svelte +16 -7
  68. package/dist/components/playground/ChatInput.svelte +11 -14
  69. package/dist/components/playground/ChatPanel.svelte +6 -49
  70. package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
  71. package/dist/components/playground/ControlPanel.svelte +134 -123
  72. package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
  73. package/dist/components/playground/ExecutionLogs.svelte +11 -9
  74. package/dist/components/playground/InputCollector.svelte +11 -9
  75. package/dist/components/playground/MessageStream.svelte +17 -23
  76. package/dist/components/playground/PipelineKanbanView.svelte +65 -6
  77. package/dist/components/playground/PipelinePanel.svelte +11 -5
  78. package/dist/components/playground/PipelineTableView.svelte +186 -44
  79. package/dist/components/playground/Playground.svelte +90 -92
  80. package/dist/components/playground/Playground.svelte.d.ts +2 -0
  81. package/dist/components/playground/PlaygroundApp.svelte +6 -1
  82. package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
  83. package/dist/components/playground/PlaygroundModal.svelte +13 -3
  84. package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
  85. package/dist/components/playground/PlaygroundStudio.svelte +34 -32
  86. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
  87. package/dist/components/playground/SessionManager.svelte +9 -12
  88. package/dist/components/playground/pipelineViewUtils.svelte.d.ts +28 -0
  89. package/dist/components/playground/pipelineViewUtils.svelte.js +38 -1
  90. package/dist/config/endpoints.d.ts +0 -7
  91. package/dist/config/endpoints.js +2 -10
  92. package/dist/core/index.d.ts +4 -4
  93. package/dist/core/index.js +6 -6
  94. package/dist/display/index.d.ts +0 -2
  95. package/dist/display/index.js +0 -6
  96. package/dist/editor/index.d.ts +19 -20
  97. package/dist/editor/index.js +25 -35
  98. package/dist/form/code.d.ts +25 -15
  99. package/dist/form/code.js +44 -41
  100. package/dist/form/fieldRegistry.d.ts +17 -13
  101. package/dist/form/fieldRegistry.js +32 -12
  102. package/dist/form/full.d.ts +17 -13
  103. package/dist/form/full.js +22 -27
  104. package/dist/form/index.d.ts +3 -3
  105. package/dist/form/index.js +3 -3
  106. package/dist/form/markdown.d.ts +13 -8
  107. package/dist/form/markdown.js +22 -23
  108. package/dist/helpers/proximityConnect.d.ts +3 -2
  109. package/dist/helpers/proximityConnect.js +2 -5
  110. package/dist/helpers/workflowEditorHelper.d.ts +12 -5
  111. package/dist/helpers/workflowEditorHelper.js +27 -25
  112. package/dist/index.d.ts +28 -24
  113. package/dist/index.js +27 -50
  114. package/dist/messages/defaults.d.ts +2 -5
  115. package/dist/messages/defaults.js +3 -6
  116. package/dist/messages/index.d.ts +0 -1
  117. package/dist/messages/index.js +0 -1
  118. package/dist/mocks/app-forms.d.ts +6 -2
  119. package/dist/mocks/app-forms.js +11 -4
  120. package/dist/openapi/v1/openapi.yaml +3 -3
  121. package/dist/playground/index.d.ts +2 -3
  122. package/dist/playground/index.js +2 -30
  123. package/dist/playground/mount.d.ts +15 -0
  124. package/dist/playground/mount.js +46 -20
  125. package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
  126. package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
  127. package/dist/registry/builtinFormats.d.ts +9 -18
  128. package/dist/registry/builtinFormats.js +9 -39
  129. package/dist/registry/builtinNodes.d.ts +0 -25
  130. package/dist/registry/builtinNodes.js +1 -50
  131. package/dist/registry/index.d.ts +3 -4
  132. package/dist/registry/index.js +4 -6
  133. package/dist/registry/nodeComponentRegistry.d.ts +182 -15
  134. package/dist/registry/nodeComponentRegistry.js +235 -17
  135. package/dist/registry/workflowFormatRegistry.d.ts +14 -9
  136. package/dist/registry/workflowFormatRegistry.js +24 -8
  137. package/dist/{schema → schemas}/index.d.ts +2 -2
  138. package/dist/{schema → schemas}/index.js +2 -2
  139. package/dist/schemas/v1/workflow.schema.json +3 -3
  140. package/dist/services/agentSpecExecutionService.js +0 -1
  141. package/dist/services/apiVariableService.d.ts +2 -1
  142. package/dist/services/apiVariableService.js +5 -22
  143. package/dist/services/autoSaveService.d.ts +7 -0
  144. package/dist/services/autoSaveService.js +6 -4
  145. package/dist/services/chatService.d.ts +8 -4
  146. package/dist/services/chatService.js +15 -15
  147. package/dist/services/draftStorage.d.ts +129 -13
  148. package/dist/services/draftStorage.js +185 -37
  149. package/dist/services/dynamicSchemaService.d.ts +2 -1
  150. package/dist/services/dynamicSchemaService.js +5 -22
  151. package/dist/services/globalSave.d.ts +13 -12
  152. package/dist/services/globalSave.js +29 -51
  153. package/dist/services/historyService.d.ts +9 -3
  154. package/dist/services/historyService.js +9 -3
  155. package/dist/services/interruptService.d.ts +14 -9
  156. package/dist/services/interruptService.js +27 -27
  157. package/dist/services/nodeExecutionService.d.ts +18 -3
  158. package/dist/services/nodeExecutionService.js +71 -45
  159. package/dist/services/playgroundService.d.ts +14 -9
  160. package/dist/services/playgroundService.js +31 -30
  161. package/dist/services/variableService.d.ts +2 -1
  162. package/dist/services/variableService.js +2 -2
  163. package/dist/services/workflowStorage.js +6 -6
  164. package/dist/stores/apiContext.d.ts +45 -0
  165. package/dist/stores/apiContext.js +65 -0
  166. package/dist/stores/categoriesStore.svelte.d.ts +28 -23
  167. package/dist/stores/categoriesStore.svelte.js +70 -64
  168. package/dist/stores/getInstance.svelte.d.ts +39 -0
  169. package/dist/stores/getInstance.svelte.js +65 -0
  170. package/dist/stores/historyStore.svelte.d.ts +77 -93
  171. package/dist/stores/historyStore.svelte.js +134 -160
  172. package/dist/stores/instanceContainer.svelte.d.ts +111 -0
  173. package/dist/stores/instanceContainer.svelte.js +114 -0
  174. package/dist/stores/interruptStore.svelte.d.ts +112 -82
  175. package/dist/stores/interruptStore.svelte.js +253 -226
  176. package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
  177. package/dist/stores/pipelinePanelStore.svelte.js +61 -14
  178. package/dist/stores/playgroundStore.svelte.d.ts +169 -222
  179. package/dist/stores/playgroundStore.svelte.js +515 -580
  180. package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
  181. package/dist/stores/portCoordinateStore.svelte.js +109 -98
  182. package/dist/stores/settingsStore.svelte.d.ts +4 -1
  183. package/dist/stores/settingsStore.svelte.js +47 -12
  184. package/dist/stores/workflowStore.svelte.d.ts +178 -213
  185. package/dist/stores/workflowStore.svelte.js +449 -501
  186. package/dist/stories/EdgeDecorator.svelte +5 -2
  187. package/dist/stories/NodeDecorator.svelte +5 -3
  188. package/dist/svelte-app.d.ts +60 -10
  189. package/dist/svelte-app.js +157 -53
  190. package/dist/types/events.d.ts +6 -3
  191. package/dist/types/index.d.ts +33 -3
  192. package/dist/types/navbar.d.ts +7 -0
  193. package/dist/types/playground.d.ts +18 -3
  194. package/dist/types/settings.d.ts +13 -0
  195. package/dist/types/settings.js +1 -0
  196. package/dist/utils/colors.d.ts +47 -21
  197. package/dist/utils/colors.js +69 -68
  198. package/dist/utils/connections.d.ts +9 -15
  199. package/dist/utils/connections.js +13 -32
  200. package/dist/utils/duration.d.ts +13 -0
  201. package/dist/utils/duration.js +45 -0
  202. package/dist/utils/icons.d.ts +5 -2
  203. package/dist/utils/icons.js +6 -5
  204. package/dist/utils/nodeSwap.d.ts +6 -2
  205. package/dist/utils/nodeSwap.js +62 -126
  206. package/dist/utils/nodeTypes.d.ts +17 -8
  207. package/dist/utils/nodeTypes.js +26 -19
  208. package/dist/utils/performanceUtils.js +7 -0
  209. package/package.json +6 -5
  210. package/dist/messages/deprecation.d.ts +0 -20
  211. package/dist/messages/deprecation.js +0 -33
  212. package/dist/registry/plugin.d.ts +0 -215
  213. package/dist/registry/plugin.js +0 -249
  214. package/dist/services/api.d.ts +0 -129
  215. package/dist/services/api.js +0 -217
@@ -13,7 +13,7 @@ import { getComponentTypeDefaults, extractComponentType, AGENTSPEC_NAMESPACE } f
13
13
  import { computeAutoLayout } from './autoLayout.js';
14
14
  import { v4 as uuidv4 } from 'uuid';
15
15
  import { logger } from '../../utils/logger.js';
16
- import { buildHandleId, extractPortId, extractDirection } from '../../utils/handleIds.js';
16
+ import { buildHandleId, extractPortId } from '../../utils/handleIds.js';
17
17
  // ============================================================================
18
18
  // Property ↔ Port Conversion
19
19
  // ============================================================================
@@ -138,7 +138,7 @@ export class AgentSpecAdapter {
138
138
  }
139
139
  }
140
140
  // Find start node
141
- const startNodeName = this.findStartNodeName(agentSpecNodes, nodeIdToName);
141
+ const startNodeName = this.findStartNodeName(agentSpecNodes);
142
142
  return {
143
143
  component_type: 'flow',
144
144
  name: workflow.name,
@@ -149,7 +149,7 @@ export class AgentSpecAdapter {
149
149
  data_flow_connections: dataFlowEdges.length > 0 ? dataFlowEdges : null,
150
150
  metadata: {
151
151
  'flowdrop:workflow_id': workflow.id,
152
- 'flowdrop:version': workflow.metadata?.version,
152
+ 'flowdrop:version': workflow.metadata?.schemaVersion,
153
153
  ...(workflow.metadata?.author ? { 'flowdrop:author': workflow.metadata.author } : {}),
154
154
  ...(workflow.metadata?.tags ? { 'flowdrop:tags': workflow.metadata.tags } : {})
155
155
  }
@@ -196,7 +196,7 @@ export class AgentSpecAdapter {
196
196
  const edges = [];
197
197
  // Control-flow edges → trigger port connections
198
198
  for (const cfEdge of agentSpecFlow.control_flow_connections) {
199
- const edge = this.convertFromControlFlowEdge(cfEdge, nameToNodeId, nodes);
199
+ const edge = this.convertFromControlFlowEdge(cfEdge, nameToNodeId);
200
200
  if (edge)
201
201
  edges.push(edge);
202
202
  }
@@ -215,7 +215,7 @@ export class AgentSpecAdapter {
215
215
  nodes,
216
216
  edges,
217
217
  metadata: {
218
- version: agentSpecFlow.metadata?.['flowdrop:version'] || '1.0.0',
218
+ schemaVersion: agentSpecFlow.metadata?.['flowdrop:version'] || '1.0.0',
219
219
  createdAt: new Date().toISOString(),
220
220
  updatedAt: new Date().toISOString(),
221
221
  author: agentSpecFlow.metadata?.['flowdrop:author'],
@@ -578,7 +578,7 @@ export class AgentSpecAdapter {
578
578
  /**
579
579
  * Convert an Agent Spec ControlFlowEdge to a FlowDrop edge.
580
580
  */
581
- convertFromControlFlowEdge(cfEdge, nameToNodeId, nodes) {
581
+ convertFromControlFlowEdge(cfEdge, nameToNodeId) {
582
582
  const sourceId = nameToNodeId.get(cfEdge.from_node);
583
583
  const targetId = nameToNodeId.get(cfEdge.to_node);
584
584
  if (!sourceId || !targetId)
@@ -615,7 +615,7 @@ export class AgentSpecAdapter {
615
615
  /**
616
616
  * Find the start node name from converted Agent Spec nodes.
617
617
  */
618
- findStartNodeName(nodes, nodeIdToName) {
618
+ findStartNodeName(nodes) {
619
619
  // Look for an explicit start_node
620
620
  const startNode = nodes.find((n) => n.component_type === 'start_node');
621
621
  if (startNode)
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Batch retry feedback for the AI Assistant.
3
+ *
4
+ * When a batch of DSL commands finishes with failures — some couldn't be
5
+ * parsed, or one failed to execute and the batch rolled back — the assistant
6
+ * needs concrete, specific feedback to self-correct. This module builds that
7
+ * message.
8
+ *
9
+ * Specificity is the point: the parse-error feedback names the offending text
10
+ * and the exact parser reason. The old generic "provide corrected commands"
11
+ * ask is what made auto-retry on parse errors loop on the same malformed shape
12
+ * — so it was disabled. Pinpointing the failure makes re-enabling it safe.
13
+ *
14
+ * @module chat/batchFeedback
15
+ */
16
+ /** A command that could not be parsed, with the reason and its raw text. */
17
+ export interface ParseFailure {
18
+ raw: string;
19
+ error: string;
20
+ }
21
+ /** Summary of how a batch finished, used to build retry feedback. */
22
+ export interface BatchOutcome {
23
+ /** Number of commands that executed successfully before stopping. */
24
+ completedCount: number;
25
+ /** Error from the first command that failed to execute, if any. */
26
+ executionError?: string;
27
+ /** Whether the executed commands were rolled back (atomic execution failure). */
28
+ rolledBack: boolean;
29
+ /** Commands that could not be parsed and were skipped. */
30
+ parseErrors: ParseFailure[];
31
+ }
32
+ /**
33
+ * Build feedback for the assistant after a batch finished with failures.
34
+ *
35
+ * Pinpoints *what* went wrong — the specific parser error and offending text
36
+ * for unparseable commands, and/or the execution error — so the assistant has
37
+ * a concrete, different target to correct.
38
+ */
39
+ export declare function buildRetryFeedback(outcome: BatchOutcome): string;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Batch retry feedback for the AI Assistant.
3
+ *
4
+ * When a batch of DSL commands finishes with failures — some couldn't be
5
+ * parsed, or one failed to execute and the batch rolled back — the assistant
6
+ * needs concrete, specific feedback to self-correct. This module builds that
7
+ * message.
8
+ *
9
+ * Specificity is the point: the parse-error feedback names the offending text
10
+ * and the exact parser reason. The old generic "provide corrected commands"
11
+ * ask is what made auto-retry on parse errors loop on the same malformed shape
12
+ * — so it was disabled. Pinpointing the failure makes re-enabling it safe.
13
+ *
14
+ * @module chat/batchFeedback
15
+ */
16
+ /**
17
+ * Build feedback for the assistant after a batch finished with failures.
18
+ *
19
+ * Pinpoints *what* went wrong — the specific parser error and offending text
20
+ * for unparseable commands, and/or the execution error — so the assistant has
21
+ * a concrete, different target to correct.
22
+ */
23
+ export function buildRetryFeedback(outcome) {
24
+ const { completedCount, executionError, rolledBack, parseErrors } = outcome;
25
+ const lines = [];
26
+ if (executionError) {
27
+ lines.push(`A command failed to execute: ${executionError}`);
28
+ lines.push(rolledBack && completedCount > 0
29
+ ? `The ${completedCount} command(s) that had succeeded were rolled back, so no changes were applied.`
30
+ : 'No changes were applied.');
31
+ }
32
+ else if (completedCount > 0) {
33
+ lines.push(`${completedCount} command(s) were applied successfully.`);
34
+ }
35
+ if (parseErrors.length > 0) {
36
+ lines.push(`\n${parseErrors.length} command(s) could not be parsed and were skipped:`);
37
+ for (const pe of parseErrors) {
38
+ const firstLine = pe.raw.split('\n')[0];
39
+ const preview = pe.raw.includes('\n') ? `${firstLine} …` : firstLine;
40
+ lines.push(` • ${preview}\n reason: ${pe.error}`);
41
+ }
42
+ lines.push('\nNote: multiline values must close with """ on its own line.');
43
+ }
44
+ if (rolledBack) {
45
+ lines.push('\nPlease re-send the full corrected batch to achieve the original goal.');
46
+ }
47
+ else {
48
+ lines.push('\nThe successful changes are reflected in the current workflow state. Re-send only corrected versions of the skipped command(s).');
49
+ }
50
+ return lines.join('\n');
51
+ }
@@ -888,17 +888,31 @@ function executeSwapNode(command, context) {
888
888
  edges: swapResult.updatedEdges
889
889
  });
890
890
  }
891
+ // Name each dropped edge so the user can see exactly what was lost
892
+ const droppedEdgeDetails = preview.droppedEdges.map(({ edge }) => {
893
+ const sourcePort = extractPortId(edge.sourceHandle ?? undefined) ?? '?';
894
+ const targetPort = extractPortId(edge.targetHandle ?? undefined) ?? '?';
895
+ return `${toShortId(edge.source)}:${sourcePort} → ${toShortId(edge.target)}:${targetPort}`;
896
+ });
891
897
  const resultData = {
892
898
  oldNodeId: toShortId(node.id),
893
899
  newNodeId: toShortId(preview.newNodeId),
894
900
  newType: command.newTypeId,
895
901
  keptEdges: preview.keptEdges.length,
896
902
  droppedEdges: preview.droppedEdges.length,
903
+ droppedEdgeDetails,
897
904
  hasDataLoss: preview.hasDataLoss,
898
905
  configCarriedOver: preview.configCarriedOver,
899
906
  configReset: preview.configReset
900
907
  };
901
- const droppedMsg = preview.droppedEdges.length > 0 ? ` (${preview.droppedEdges.length} edge(s) dropped)` : '';
908
+ // Cap the inline list a badly mismatched swap can drop dozens of edges,
909
+ // and the full list is always available in resultData.droppedEdgeDetails
910
+ const MAX_NAMED_DROPPED_EDGES = 5;
911
+ const namedDropped = droppedEdgeDetails.slice(0, MAX_NAMED_DROPPED_EDGES);
912
+ const unnamedCount = droppedEdgeDetails.length - namedDropped.length;
913
+ const droppedMsg = preview.droppedEdges.length > 0
914
+ ? ` (${preview.droppedEdges.length} edge(s) dropped: ${namedDropped.join(', ')}${unnamedCount > 0 ? `, … and ${unnamedCount} more` : ''})`
915
+ : '';
902
916
  return {
903
917
  ok: true,
904
918
  message: `Swapped ${toShortId(node.id)} → ${toShortId(preview.newNodeId)} (${command.newTypeId})${droppedMsg}`,
@@ -4,6 +4,7 @@
4
4
  * Bridges the command system to the live Svelte stores.
5
5
  * This is the only Svelte-coupled file in commands/.
6
6
  */
7
+ import { type FlowDropInstance } from '../stores/instanceContainer.svelte.js';
7
8
  import { type CommandContext, type UIAction } from './types.js';
8
9
  import type { NodeMetadata } from '../types/index.js';
9
10
  /**
@@ -11,6 +12,8 @@ import type { NodeMetadata } from '../types/index.js';
11
12
  *
12
13
  * @param nodeTypes - Available node type definitions
13
14
  * @param onUIAction - Optional callback for UI-side actions (open config panel, select node)
15
+ * @param instance - The FlowDrop instance to operate on; defaults to the
16
+ * page-default instance when omitted
14
17
  * @returns CommandContext connected to live stores, or null if no workflow is loaded
15
18
  */
16
- export declare function createStoreCommandContext(nodeTypes: NodeMetadata[], onUIAction?: (action: UIAction) => void): CommandContext | null;
19
+ export declare function createStoreCommandContext(nodeTypes: NodeMetadata[], onUIAction?: (action: UIAction) => void, instance?: FlowDropInstance): CommandContext | null;
@@ -4,62 +4,67 @@
4
4
  * Bridges the command system to the live Svelte stores.
5
5
  * This is the only Svelte-coupled file in commands/.
6
6
  */
7
- import { getWorkflowStore, workflowActions } from '../stores/workflowStore.svelte.js';
8
- import { historyService } from '../services/historyService.js';
7
+ import { getDefaultInstance } from '../stores/instanceContainer.svelte.js';
9
8
  import { buildTypeMap } from './types.js';
10
9
  /**
11
10
  * Creates a CommandContext that bridges the command system to the live Svelte stores.
12
11
  *
13
12
  * @param nodeTypes - Available node type definitions
14
13
  * @param onUIAction - Optional callback for UI-side actions (open config panel, select node)
14
+ * @param instance - The FlowDrop instance to operate on; defaults to the
15
+ * page-default instance when omitted
15
16
  * @returns CommandContext connected to live stores, or null if no workflow is loaded
16
17
  */
17
- export function createStoreCommandContext(nodeTypes, onUIAction) {
18
- const workflow = getWorkflowStore();
18
+ export function createStoreCommandContext(nodeTypes, onUIAction, instance) {
19
+ const fd = instance ?? getDefaultInstance();
20
+ const readWorkflow = () => fd.workflow.current;
21
+ const actions = fd.workflow.actions;
22
+ const history = fd.history;
23
+ const workflow = readWorkflow();
19
24
  if (!workflow) {
20
25
  return null;
21
26
  }
22
27
  const dispatch = {
23
- addNode: (node) => workflowActions.addNode(node),
24
- removeNode: (nodeId) => workflowActions.removeNode(nodeId),
25
- updateNode: (nodeId, updates) => workflowActions.updateNode(nodeId, updates),
26
- addEdge: (edge) => workflowActions.addEdge(edge),
27
- removeEdge: (edgeId) => workflowActions.removeEdge(edgeId),
28
- batchUpdate: (updates) => workflowActions.batchUpdate(updates),
28
+ addNode: (node) => actions.addNode(node),
29
+ removeNode: (nodeId) => actions.removeNode(nodeId),
30
+ updateNode: (nodeId, updates) => actions.updateNode(nodeId, updates),
31
+ addEdge: (edge) => actions.addEdge(edge),
32
+ removeEdge: (edgeId) => actions.removeEdge(edgeId),
33
+ batchUpdate: (updates) => actions.batchUpdate(updates),
29
34
  undo: () => {
30
- const previousState = historyService.undo();
35
+ const previousState = history.undo();
31
36
  if (previousState) {
32
- workflowActions.restoreFromHistory(previousState);
37
+ actions.restoreFromHistory(previousState);
33
38
  return true;
34
39
  }
35
40
  return false;
36
41
  },
37
42
  redo: () => {
38
- const nextState = historyService.redo();
43
+ const nextState = history.redo();
39
44
  if (nextState) {
40
- workflowActions.restoreFromHistory(nextState);
45
+ actions.restoreFromHistory(nextState);
41
46
  return true;
42
47
  }
43
48
  return false;
44
49
  },
45
50
  startTransaction: (description) => {
46
- const currentWorkflow = getWorkflowStore();
51
+ const currentWorkflow = readWorkflow();
47
52
  if (currentWorkflow) {
48
- historyService.startTransaction(currentWorkflow, description);
53
+ history.startTransaction(currentWorkflow, description);
49
54
  }
50
55
  },
51
- commitTransaction: () => historyService.commitTransaction(),
56
+ commitTransaction: () => history.commitTransaction(),
52
57
  cancelTransaction: () => {
53
- const snapshot = historyService.cancelTransaction();
58
+ const snapshot = history.cancelTransaction();
54
59
  if (snapshot) {
55
- workflowActions.restoreFromHistory(snapshot);
60
+ actions.restoreFromHistory(snapshot);
56
61
  }
57
62
  },
58
63
  emitUIAction: onUIAction,
59
- swapNode: (updates) => workflowActions.swapNode(updates)
64
+ swapNode: (updates) => actions.swapNode(updates)
60
65
  };
61
66
  return {
62
- getWorkflow: () => getWorkflowStore(),
67
+ getWorkflow: () => readWorkflow(),
63
68
  nodeTypes,
64
69
  typeMap: buildTypeMap(nodeTypes),
65
70
  dispatch
@@ -244,6 +244,8 @@ export interface SwapNodeResultData {
244
244
  newType: string;
245
245
  keptEdges: number;
246
246
  droppedEdges: number;
247
+ /** Human-readable descriptions of each dropped edge, e.g. "node.1:text → node.2:message" */
248
+ droppedEdgeDetails: string[];
247
249
  hasDataLoss: boolean;
248
250
  configCarriedOver: string[];
249
251
  configReset: string[];