@flowdrop/flowdrop 1.14.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.
- package/CHANGELOG.md +475 -0
- package/MIGRATION-2.0.md +472 -0
- package/README.md +23 -23
- package/dist/adapters/WorkflowAdapter.d.ts +1 -1
- package/dist/adapters/WorkflowAdapter.js +14 -8
- package/dist/adapters/agentspec/AgentSpecAdapter.js +7 -7
- package/dist/chat/batchFeedback.d.ts +39 -0
- package/dist/chat/batchFeedback.js +51 -0
- package/dist/commands/executor.js +15 -1
- package/dist/commands/storeIntegration.svelte.d.ts +4 -1
- package/dist/commands/storeIntegration.svelte.js +26 -21
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/App.svelte +162 -192
- package/dist/components/App.svelte.d.ts +47 -8
- package/dist/components/ConfigForm.svelte +110 -66
- package/dist/components/ConfigModal.svelte +7 -2
- package/dist/components/ConnectionLine.svelte +4 -2
- package/dist/components/Navbar.svelte +61 -1
- package/dist/components/NodeSidebar.svelte +27 -45
- package/dist/components/NodeStatusOverlay.svelte +94 -6
- package/dist/components/NodeSwapPicker.svelte +10 -8
- package/dist/components/PipelineStatus.svelte +16 -67
- package/dist/components/PortCoordinateTracker.svelte +5 -6
- package/dist/components/SchemaForm.stories.svelte +1 -3
- package/dist/components/SchemaForm.svelte +45 -40
- package/dist/components/SchemaForm.svelte.d.ts +0 -8
- package/dist/components/SettingsModal.svelte +8 -3
- package/dist/components/SettingsPanel.svelte +20 -4
- package/dist/components/SwapMappingEditor.svelte +67 -49
- package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
- package/dist/components/UniversalNode.svelte +9 -7
- package/dist/components/WorkflowEditor.svelte +118 -111
- package/dist/components/WorkflowEditor.svelte.d.ts +18 -10
- package/dist/components/chat/AIChatPanel.svelte +93 -89
- package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
- package/dist/components/chat/CommandPreview.svelte +2 -1
- package/dist/components/console/CommandConsole.svelte +7 -5
- package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
- package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
- package/dist/components/console/ConsoleInput.svelte +15 -6
- package/dist/components/console/ConsoleOutput.svelte +2 -1
- package/dist/components/form/FormArray.svelte +5 -9
- package/dist/components/form/FormArray.svelte.d.ts +2 -1
- package/dist/components/form/FormAutocomplete.svelte +29 -13
- package/dist/components/form/FormField.svelte +4 -2
- package/dist/components/form/FormFieldLight.svelte +4 -2
- package/dist/components/form/FormMarkdownEditor.svelte +9 -4
- package/dist/components/form/FormRangeField.svelte +1 -0
- package/dist/components/form/FormTemplateEditor.svelte +11 -3
- package/dist/components/form/FormToggle.svelte +5 -12
- package/dist/components/form/FormToggle.svelte.d.ts +4 -2
- package/dist/components/form/templateAutocomplete.js +1 -5
- package/dist/components/form/types.d.ts +1 -14
- package/dist/components/interrupt/FormPrompt.svelte +3 -2
- package/dist/components/interrupt/InterruptBubble.svelte +16 -17
- package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
- package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
- package/dist/components/layouts/MainLayout.svelte +20 -13
- package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
- package/dist/components/nodes/AtomNode.svelte +292 -0
- package/dist/components/nodes/AtomNode.svelte.d.ts +26 -0
- package/dist/components/nodes/GatewayNode.svelte +19 -10
- package/dist/components/nodes/IdeaNode.svelte +7 -0
- package/dist/components/nodes/SimpleNode.svelte +11 -6
- package/dist/components/nodes/SquareNode.svelte +15 -8
- package/dist/components/nodes/TerminalNode.svelte +9 -4
- package/dist/components/nodes/ToolNode.svelte +7 -1
- package/dist/components/nodes/WorkflowNode.svelte +16 -7
- package/dist/components/playground/ChatInput.svelte +11 -14
- package/dist/components/playground/ChatPanel.svelte +6 -49
- package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
- package/dist/components/playground/ControlPanel.svelte +134 -123
- package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
- package/dist/components/playground/ExecutionLogs.svelte +11 -9
- package/dist/components/playground/InputCollector.svelte +11 -9
- package/dist/components/playground/MessageStream.svelte +17 -23
- package/dist/components/playground/PipelineKanbanView.svelte +65 -6
- package/dist/components/playground/PipelinePanel.svelte +11 -5
- package/dist/components/playground/PipelineTableView.svelte +186 -44
- package/dist/components/playground/Playground.svelte +95 -92
- package/dist/components/playground/Playground.svelte.d.ts +2 -0
- package/dist/components/playground/PlaygroundApp.svelte +6 -1
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundModal.svelte +13 -3
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundStudio.svelte +34 -32
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
- package/dist/components/playground/SessionManager.svelte +9 -12
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +28 -0
- package/dist/components/playground/pipelineViewUtils.svelte.js +38 -1
- package/dist/config/endpoints.d.ts +0 -7
- package/dist/config/endpoints.js +2 -10
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +6 -6
- package/dist/display/index.d.ts +0 -2
- package/dist/display/index.js +0 -6
- package/dist/editor/index.d.ts +19 -20
- package/dist/editor/index.js +25 -35
- package/dist/form/code.d.ts +25 -15
- package/dist/form/code.js +44 -41
- package/dist/form/fieldRegistry.d.ts +17 -13
- package/dist/form/fieldRegistry.js +32 -12
- package/dist/form/full.d.ts +17 -13
- package/dist/form/full.js +22 -27
- package/dist/form/index.d.ts +3 -3
- package/dist/form/index.js +3 -3
- package/dist/form/markdown.d.ts +13 -8
- package/dist/form/markdown.js +22 -23
- package/dist/helpers/proximityConnect.d.ts +7 -3
- package/dist/helpers/proximityConnect.js +19 -6
- package/dist/helpers/workflowEditorHelper.d.ts +12 -5
- package/dist/helpers/workflowEditorHelper.js +27 -25
- package/dist/index.d.ts +28 -24
- package/dist/index.js +27 -50
- package/dist/messages/defaults.d.ts +2 -5
- package/dist/messages/defaults.js +3 -6
- package/dist/messages/index.d.ts +0 -1
- package/dist/messages/index.js +0 -1
- package/dist/mocks/app-forms.d.ts +6 -2
- package/dist/mocks/app-forms.js +11 -4
- package/dist/openapi/v1/openapi.yaml +227 -164
- package/dist/playground/index.d.ts +2 -3
- package/dist/playground/index.js +2 -30
- package/dist/playground/mount.d.ts +15 -0
- package/dist/playground/mount.js +46 -20
- package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
- package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
- package/dist/registry/builtinFormats.d.ts +9 -18
- package/dist/registry/builtinFormats.js +9 -39
- package/dist/registry/builtinNodes.d.ts +1 -26
- package/dist/registry/builtinNodes.js +14 -50
- package/dist/registry/index.d.ts +3 -4
- package/dist/registry/index.js +4 -6
- package/dist/registry/nodeComponentRegistry.d.ts +182 -15
- package/dist/registry/nodeComponentRegistry.js +235 -17
- package/dist/registry/workflowFormatRegistry.d.ts +14 -9
- package/dist/registry/workflowFormatRegistry.js +24 -8
- package/dist/{schema → schemas}/index.d.ts +2 -2
- package/dist/{schema → schemas}/index.js +2 -2
- package/dist/schemas/v1/workflow.schema.json +53 -6
- package/dist/services/agentSpecExecutionService.js +0 -1
- package/dist/services/apiVariableService.d.ts +2 -1
- package/dist/services/apiVariableService.js +5 -22
- package/dist/services/autoSaveService.d.ts +7 -0
- package/dist/services/autoSaveService.js +6 -4
- package/dist/services/chatService.d.ts +8 -4
- package/dist/services/chatService.js +15 -15
- package/dist/services/draftStorage.d.ts +129 -13
- package/dist/services/draftStorage.js +185 -37
- package/dist/services/dynamicSchemaService.d.ts +2 -1
- package/dist/services/dynamicSchemaService.js +5 -22
- package/dist/services/globalSave.d.ts +13 -12
- package/dist/services/globalSave.js +29 -51
- package/dist/services/historyService.d.ts +9 -3
- package/dist/services/historyService.js +9 -3
- package/dist/services/interruptService.d.ts +14 -9
- package/dist/services/interruptService.js +27 -27
- package/dist/services/nodeExecutionService.d.ts +18 -3
- package/dist/services/nodeExecutionService.js +71 -45
- package/dist/services/playgroundService.d.ts +14 -9
- package/dist/services/playgroundService.js +31 -30
- package/dist/services/variableService.d.ts +2 -1
- package/dist/services/variableService.js +2 -2
- package/dist/services/workflowStorage.js +6 -6
- package/dist/stores/apiContext.d.ts +45 -0
- package/dist/stores/apiContext.js +65 -0
- package/dist/stores/categoriesStore.svelte.d.ts +28 -23
- package/dist/stores/categoriesStore.svelte.js +70 -64
- package/dist/stores/getInstance.svelte.d.ts +39 -0
- package/dist/stores/getInstance.svelte.js +65 -0
- package/dist/stores/historyStore.svelte.d.ts +77 -93
- package/dist/stores/historyStore.svelte.js +134 -160
- package/dist/stores/instanceContainer.svelte.d.ts +111 -0
- package/dist/stores/instanceContainer.svelte.js +114 -0
- package/dist/stores/interruptStore.svelte.d.ts +112 -82
- package/dist/stores/interruptStore.svelte.js +253 -226
- package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
- package/dist/stores/pipelinePanelStore.svelte.js +61 -14
- package/dist/stores/playgroundStore.svelte.d.ts +169 -216
- package/dist/stores/playgroundStore.svelte.js +515 -572
- package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
- package/dist/stores/portCoordinateStore.svelte.js +109 -98
- package/dist/stores/settingsStore.svelte.d.ts +4 -1
- package/dist/stores/settingsStore.svelte.js +47 -12
- package/dist/stores/workflowStore.svelte.d.ts +178 -213
- package/dist/stores/workflowStore.svelte.js +449 -501
- package/dist/stories/EdgeDecorator.svelte +5 -2
- package/dist/stories/NodeDecorator.svelte +5 -3
- package/dist/svelte-app.d.ts +60 -10
- package/dist/svelte-app.js +157 -53
- package/dist/types/events.d.ts +6 -3
- package/dist/types/index.d.ts +71 -6
- package/dist/types/navbar.d.ts +7 -0
- package/dist/types/playground.d.ts +18 -3
- package/dist/types/settings.d.ts +13 -0
- package/dist/types/settings.js +1 -0
- package/dist/utils/colors.d.ts +47 -21
- package/dist/utils/colors.js +69 -68
- package/dist/utils/connections.d.ts +9 -15
- package/dist/utils/connections.js +13 -32
- package/dist/utils/duration.d.ts +13 -0
- package/dist/utils/duration.js +45 -0
- package/dist/utils/formMerge.d.ts +36 -0
- package/dist/utils/formMerge.js +70 -0
- package/dist/utils/icons.d.ts +5 -2
- package/dist/utils/icons.js +6 -5
- package/dist/utils/nodeSwap.d.ts +6 -2
- package/dist/utils/nodeSwap.js +62 -126
- package/dist/utils/nodeTypes.d.ts +17 -8
- package/dist/utils/nodeTypes.js +27 -19
- package/dist/utils/performanceUtils.js +7 -0
- package/package.json +6 -5
- package/dist/messages/deprecation.d.ts +0 -20
- package/dist/messages/deprecation.js +0 -33
- package/dist/registry/plugin.d.ts +0 -215
- package/dist/registry/plugin.js +0 -249
- package/dist/services/api.d.ts +0 -129
- 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
|
|
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
|
|
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?.
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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) =>
|
|
24
|
-
removeNode: (nodeId) =>
|
|
25
|
-
updateNode: (nodeId, updates) =>
|
|
26
|
-
addEdge: (edge) =>
|
|
27
|
-
removeEdge: (edgeId) =>
|
|
28
|
-
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 =
|
|
35
|
+
const previousState = history.undo();
|
|
31
36
|
if (previousState) {
|
|
32
|
-
|
|
37
|
+
actions.restoreFromHistory(previousState);
|
|
33
38
|
return true;
|
|
34
39
|
}
|
|
35
40
|
return false;
|
|
36
41
|
},
|
|
37
42
|
redo: () => {
|
|
38
|
-
const nextState =
|
|
43
|
+
const nextState = history.redo();
|
|
39
44
|
if (nextState) {
|
|
40
|
-
|
|
45
|
+
actions.restoreFromHistory(nextState);
|
|
41
46
|
return true;
|
|
42
47
|
}
|
|
43
48
|
return false;
|
|
44
49
|
},
|
|
45
50
|
startTransaction: (description) => {
|
|
46
|
-
const currentWorkflow =
|
|
51
|
+
const currentWorkflow = readWorkflow();
|
|
47
52
|
if (currentWorkflow) {
|
|
48
|
-
|
|
53
|
+
history.startTransaction(currentWorkflow, description);
|
|
49
54
|
}
|
|
50
55
|
},
|
|
51
|
-
commitTransaction: () =>
|
|
56
|
+
commitTransaction: () => history.commitTransaction(),
|
|
52
57
|
cancelTransaction: () => {
|
|
53
|
-
const snapshot =
|
|
58
|
+
const snapshot = history.cancelTransaction();
|
|
54
59
|
if (snapshot) {
|
|
55
|
-
|
|
60
|
+
actions.restoreFromHistory(snapshot);
|
|
56
61
|
}
|
|
57
62
|
},
|
|
58
63
|
emitUIAction: onUIAction,
|
|
59
|
-
swapNode: (updates) =>
|
|
64
|
+
swapNode: (updates) => actions.swapNode(updates)
|
|
60
65
|
};
|
|
61
66
|
return {
|
|
62
|
-
getWorkflow: () =>
|
|
67
|
+
getWorkflow: () => readWorkflow(),
|
|
63
68
|
nodeTypes,
|
|
64
69
|
typeMap: buildTypeMap(nodeTypes),
|
|
65
70
|
dispatch
|
package/dist/commands/types.d.ts
CHANGED
|
@@ -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[];
|