@flowdrop/flowdrop 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +68 -24
  2. package/dist/adapters/WorkflowAdapter.js +2 -22
  3. package/dist/adapters/agentspec/autoLayout.d.ts +51 -5
  4. package/dist/adapters/agentspec/autoLayout.js +120 -23
  5. package/dist/chat/commandClassifier.d.ts +19 -0
  6. package/dist/chat/commandClassifier.js +30 -0
  7. package/dist/chat/index.d.ts +27 -0
  8. package/dist/chat/index.js +32 -0
  9. package/dist/chat/responseParser.d.ts +21 -0
  10. package/dist/chat/responseParser.js +87 -0
  11. package/dist/commands/batch.d.ts +18 -0
  12. package/dist/commands/batch.js +56 -0
  13. package/dist/commands/executor.d.ts +37 -0
  14. package/dist/commands/executor.js +1044 -0
  15. package/dist/commands/index.d.ts +14 -0
  16. package/dist/commands/index.js +17 -0
  17. package/dist/commands/parser.d.ts +16 -0
  18. package/dist/commands/parser.js +278 -0
  19. package/dist/commands/positioner.d.ts +19 -0
  20. package/dist/commands/positioner.js +33 -0
  21. package/dist/commands/storeIntegration.svelte.d.ts +16 -0
  22. package/dist/commands/storeIntegration.svelte.js +67 -0
  23. package/dist/commands/types.d.ts +343 -0
  24. package/dist/commands/types.js +45 -0
  25. package/dist/components/App.svelte +351 -12
  26. package/dist/components/App.svelte.d.ts +3 -0
  27. package/dist/components/CanvasController.svelte +38 -0
  28. package/dist/components/CanvasController.svelte.d.ts +32 -0
  29. package/dist/components/ConfigMappingRow.svelte +130 -0
  30. package/dist/components/ConfigMappingRow.svelte.d.ts +8 -0
  31. package/dist/components/ConfigPanel.svelte +56 -7
  32. package/dist/components/ConfigPanel.svelte.d.ts +2 -0
  33. package/dist/components/FlowDropEdge.svelte +2 -10
  34. package/dist/components/LogsSidebar.svelte +5 -5
  35. package/dist/components/NodeSidebar.svelte +15 -49
  36. package/dist/components/NodeSwapPicker.svelte +537 -0
  37. package/dist/components/NodeSwapPicker.svelte.d.ts +16 -0
  38. package/dist/components/PortMappingRow.svelte +209 -0
  39. package/dist/components/PortMappingRow.svelte.d.ts +12 -0
  40. package/dist/components/SwapMappingEditor.svelte +550 -0
  41. package/dist/components/SwapMappingEditor.svelte.d.ts +12 -0
  42. package/dist/components/WorkflowEditor.svelte +99 -4
  43. package/dist/components/WorkflowEditor.svelte.d.ts +8 -0
  44. package/dist/components/chat/AIChatPanel.svelte +658 -0
  45. package/dist/components/chat/AIChatPanel.svelte.d.ts +13 -0
  46. package/dist/components/chat/CommandPreview.svelte +184 -0
  47. package/dist/components/chat/CommandPreview.svelte.d.ts +9 -0
  48. package/dist/components/console/CommandConsole.stories.svelte +93 -0
  49. package/dist/components/console/CommandConsole.stories.svelte.d.ts +27 -0
  50. package/dist/components/console/CommandConsole.svelte +259 -0
  51. package/dist/components/console/CommandConsole.svelte.d.ts +11 -0
  52. package/dist/components/console/ConsoleAutocomplete.svelte +139 -0
  53. package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +21 -0
  54. package/dist/components/console/ConsoleInput.svelte +712 -0
  55. package/dist/components/console/ConsoleInput.svelte.d.ts +16 -0
  56. package/dist/components/console/ConsoleOutput.svelte +121 -0
  57. package/dist/components/console/ConsoleOutput.svelte.d.ts +11 -0
  58. package/dist/components/console/formatters.d.ts +26 -0
  59. package/dist/components/console/formatters.js +118 -0
  60. package/dist/components/interrupt/index.d.ts +1 -0
  61. package/dist/components/interrupt/index.js +1 -0
  62. package/dist/config/endpoints.d.ts +8 -0
  63. package/dist/config/endpoints.js +5 -0
  64. package/dist/core/index.d.ts +5 -0
  65. package/dist/core/index.js +9 -0
  66. package/dist/editor/index.d.ts +3 -1
  67. package/dist/editor/index.js +4 -2
  68. package/dist/helpers/proximityConnect.js +8 -1
  69. package/dist/helpers/workflowEditorHelper.d.ts +3 -53
  70. package/dist/helpers/workflowEditorHelper.js +13 -228
  71. package/dist/playground/index.d.ts +1 -1
  72. package/dist/playground/index.js +1 -1
  73. package/dist/schemas/v1/workflow.schema.json +107 -22
  74. package/dist/services/chatService.d.ts +65 -0
  75. package/dist/services/chatService.js +131 -0
  76. package/dist/services/historyService.d.ts +6 -4
  77. package/dist/services/historyService.js +21 -6
  78. package/dist/stores/interruptStore.svelte.js +6 -1
  79. package/dist/stores/playgroundStore.svelte.d.ts +1 -1
  80. package/dist/stores/playgroundStore.svelte.js +11 -2
  81. package/dist/stores/portCoordinateStore.svelte.d.ts +4 -0
  82. package/dist/stores/portCoordinateStore.svelte.js +20 -26
  83. package/dist/stores/workflowStore.svelte.d.ts +31 -2
  84. package/dist/stores/workflowStore.svelte.js +84 -64
  85. package/dist/types/chat.d.ts +63 -0
  86. package/dist/types/chat.js +9 -0
  87. package/dist/types/events.d.ts +28 -2
  88. package/dist/types/events.js +1 -0
  89. package/dist/types/index.d.ts +8 -0
  90. package/dist/types/settings.d.ts +6 -0
  91. package/dist/types/settings.js +3 -0
  92. package/dist/utils/edgeStyling.d.ts +42 -0
  93. package/dist/utils/edgeStyling.js +176 -0
  94. package/dist/utils/nodeIds.d.ts +31 -0
  95. package/dist/utils/nodeIds.js +42 -0
  96. package/dist/utils/nodeSwap.d.ts +221 -0
  97. package/dist/utils/nodeSwap.js +686 -0
  98. package/package.json +6 -1
  99. package/dist/helpers/nodeLayoutHelper.d.ts +0 -14
  100. package/dist/helpers/nodeLayoutHelper.js +0 -19
@@ -0,0 +1,184 @@
1
+ <script lang="ts">
2
+ import type { CommandPreviewItem } from "../../types/chat.js";
3
+ import Icon from "@iconify/svelte";
4
+
5
+ interface Props {
6
+ commands: CommandPreviewItem[];
7
+ onApprove: () => void;
8
+ onCancel: () => void;
9
+ }
10
+
11
+ let { commands, onApprove, onCancel }: Props = $props();
12
+
13
+ const hasPending = $derived(commands.some((c) => c.status === "pending"));
14
+ const isExecuting = $derived(commands.some((c) => c.status === "executing"));
15
+ </script>
16
+
17
+ <div class="command-preview" role="region" aria-label="Command preview">
18
+ <div class="command-preview__list">
19
+ {#each commands as command, i}
20
+ <div class="command-preview__item command-preview__item--{command.status}">
21
+ <span class="command-preview__status">
22
+ {#if command.status === "pending"}
23
+ <Icon icon="mdi:chevron-right" />
24
+ {:else if command.status === "executing"}
25
+ <Icon icon="mdi:loading" />
26
+ {:else if command.status === "success"}
27
+ <Icon icon="mdi:check-circle" />
28
+ {:else if command.status === "error"}
29
+ <Icon icon="mdi:alert-circle" />
30
+ {/if}
31
+ </span>
32
+ <pre class="command-preview__command">{command.raw}</pre>
33
+ {#if command.status === "error" && command.result}
34
+ <span class="command-preview__error">{command.result}</span>
35
+ {/if}
36
+ </div>
37
+ {/each}
38
+ </div>
39
+
40
+ <div class="command-preview__actions">
41
+ <button
42
+ class="command-preview__btn command-preview__btn--approve"
43
+ onclick={onApprove}
44
+ disabled={!hasPending || isExecuting}
45
+ >
46
+ <Icon icon="mdi:check-all" />
47
+ Apply All
48
+ </button>
49
+ <button
50
+ class="command-preview__btn command-preview__btn--cancel"
51
+ onclick={onCancel}
52
+ disabled={isExecuting}
53
+ >
54
+ Cancel
55
+ </button>
56
+ </div>
57
+ </div>
58
+
59
+ <style>
60
+ .command-preview {
61
+ border: 1px solid var(--fd-border);
62
+ border-radius: var(--fd-radius-md);
63
+ background: var(--fd-card);
64
+ overflow: hidden;
65
+ }
66
+
67
+ .command-preview__list {
68
+ display: flex;
69
+ flex-direction: column;
70
+ padding: var(--fd-space-xs);
71
+ gap: var(--fd-space-3xs);
72
+ }
73
+
74
+ .command-preview__item {
75
+ display: flex;
76
+ align-items: flex-start;
77
+ gap: var(--fd-space-2xs);
78
+ padding: var(--fd-space-3xs) var(--fd-space-xs);
79
+ border-radius: var(--fd-radius-sm);
80
+ }
81
+
82
+ .command-preview__status {
83
+ display: flex;
84
+ align-items: center;
85
+ flex-shrink: 0;
86
+ font-size: var(--fd-text-xs);
87
+ /* align icon with the first line of the pre block */
88
+ margin-top: 1px;
89
+ line-height: 1.5;
90
+ }
91
+
92
+ .command-preview__item--pending .command-preview__status {
93
+ color: var(--fd-muted-foreground);
94
+ }
95
+
96
+ .command-preview__item--executing .command-preview__status {
97
+ color: var(--fd-info);
98
+ animation: spin 1s linear infinite;
99
+ }
100
+
101
+ .command-preview__item--success .command-preview__status {
102
+ color: var(--fd-success);
103
+ }
104
+
105
+ .command-preview__item--error .command-preview__status {
106
+ color: var(--fd-error);
107
+ }
108
+
109
+ @keyframes spin {
110
+ from {
111
+ transform: rotate(0deg);
112
+ }
113
+ to {
114
+ transform: rotate(360deg);
115
+ }
116
+ }
117
+
118
+ .command-preview__command {
119
+ font-family: var(--fd-font-mono);
120
+ font-size: var(--fd-text-xs);
121
+ line-height: 1.5;
122
+ color: var(--fd-foreground);
123
+ white-space: pre-wrap;
124
+ word-break: break-word;
125
+ margin: 0;
126
+ }
127
+
128
+ .command-preview__item--error .command-preview__command {
129
+ color: var(--fd-error);
130
+ }
131
+
132
+ .command-preview__error {
133
+ display: block;
134
+ font-size: var(--fd-text-xs);
135
+ color: var(--fd-error);
136
+ margin-top: var(--fd-space-3xs);
137
+ }
138
+
139
+ .command-preview__actions {
140
+ display: flex;
141
+ gap: var(--fd-space-xs);
142
+ padding: var(--fd-space-xs);
143
+ border-top: 1px solid var(--fd-border);
144
+ background: var(--fd-muted);
145
+ }
146
+
147
+ .command-preview__btn {
148
+ display: inline-flex;
149
+ align-items: center;
150
+ gap: var(--fd-space-3xs);
151
+ padding: var(--fd-space-3xs) var(--fd-space-sm);
152
+ border: none;
153
+ border-radius: var(--fd-radius-sm);
154
+ font-size: var(--fd-text-xs);
155
+ font-weight: 600;
156
+ cursor: pointer;
157
+ transition:
158
+ background-color var(--fd-transition-fast),
159
+ color var(--fd-transition-fast);
160
+ }
161
+
162
+ .command-preview__btn:disabled {
163
+ opacity: 0.5;
164
+ cursor: not-allowed;
165
+ }
166
+
167
+ .command-preview__btn--approve {
168
+ background: var(--fd-primary);
169
+ color: var(--fd-primary-foreground);
170
+ }
171
+
172
+ .command-preview__btn--approve:hover:not(:disabled) {
173
+ background: var(--fd-primary-hover);
174
+ }
175
+
176
+ .command-preview__btn--cancel {
177
+ background: var(--fd-secondary);
178
+ color: var(--fd-secondary-foreground);
179
+ }
180
+
181
+ .command-preview__btn--cancel:hover:not(:disabled) {
182
+ background: var(--fd-secondary-hover);
183
+ }
184
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { CommandPreviewItem } from "../../types/chat.js";
2
+ interface Props {
3
+ commands: CommandPreviewItem[];
4
+ onApprove: () => void;
5
+ onCancel: () => void;
6
+ }
7
+ declare const CommandPreview: import("svelte").Component<Props, {}, "">;
8
+ type CommandPreview = ReturnType<typeof CommandPreview>;
9
+ export default CommandPreview;
@@ -0,0 +1,93 @@
1
+ <script module>
2
+ import { defineMeta } from "@storybook/addon-svelte-csf";
3
+ import CommandConsole from "./CommandConsole.svelte";
4
+ import { fn } from "storybook/test";
5
+
6
+ const mockNodeTypes = [
7
+ {
8
+ id: "llm_chat",
9
+ name: "LLM Chat",
10
+ description: "Chat completion using an LLM provider",
11
+ category: "AI",
12
+ version: "1.0.0",
13
+ inputs: [
14
+ { id: "prompt", name: "Prompt", type: "input", dataType: "string" },
15
+ { id: "context", name: "Context", type: "input", dataType: "string" },
16
+ ],
17
+ outputs: [
18
+ { id: "response", name: "Response", type: "output", dataType: "string" },
19
+ ],
20
+ configSchema: {
21
+ type: "object",
22
+ properties: {
23
+ model: { type: "string", default: "gpt-4" },
24
+ temperature: { type: "number", default: 0.7 },
25
+ maxTokens: { type: "number", default: 1024 },
26
+ },
27
+ },
28
+ },
29
+ {
30
+ id: "http_request",
31
+ name: "HTTP Request",
32
+ description: "Send HTTP requests to external APIs",
33
+ category: "Integration",
34
+ version: "1.0.0",
35
+ inputs: [
36
+ { id: "url", name: "URL", type: "input", dataType: "string" },
37
+ { id: "body", name: "Body", type: "input", dataType: "object" },
38
+ ],
39
+ outputs: [
40
+ { id: "response", name: "Response", type: "output", dataType: "object" },
41
+ { id: "status", name: "Status Code", type: "output", dataType: "number" },
42
+ ],
43
+ configSchema: {
44
+ type: "object",
45
+ properties: {
46
+ method: { type: "string", default: "GET" },
47
+ headers: { type: "object", default: {} },
48
+ timeout: { type: "number", default: 30000 },
49
+ },
50
+ },
51
+ },
52
+ {
53
+ id: "text_template",
54
+ name: "Text Template",
55
+ description: "Render text templates with variable substitution",
56
+ category: "Transform",
57
+ version: "1.0.0",
58
+ inputs: [
59
+ { id: "variables", name: "Variables", type: "input", dataType: "object" },
60
+ ],
61
+ outputs: [
62
+ { id: "text", name: "Text", type: "output", dataType: "string" },
63
+ ],
64
+ configSchema: {
65
+ type: "object",
66
+ properties: {
67
+ template: { type: "string", default: "" },
68
+ delimiter: { type: "string", default: "{{" },
69
+ },
70
+ },
71
+ },
72
+ ];
73
+
74
+ const { Story } = defineMeta({
75
+ title: "Editor/CommandConsole",
76
+ component: CommandConsole,
77
+ tags: ["autodocs"],
78
+ parameters: {
79
+ layout: "padded",
80
+ },
81
+ args: {
82
+ nodeTypes: mockNodeTypes,
83
+ onUIAction: fn(),
84
+ },
85
+ });
86
+ </script>
87
+
88
+ <Story
89
+ name="Default"
90
+ args={{
91
+ nodeTypes: mockNodeTypes,
92
+ }}
93
+ />
@@ -0,0 +1,27 @@
1
+ export default CommandConsole;
2
+ type CommandConsole = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const CommandConsole: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ import CommandConsole from "./CommandConsole.svelte";
15
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
16
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
17
+ $$bindings?: Bindings;
18
+ } & Exports;
19
+ (internal: unknown, props: {
20
+ $$events?: Events;
21
+ $$slots?: Slots;
22
+ }): Exports & {
23
+ $set?: any;
24
+ $on?: any;
25
+ };
26
+ z_$$bindings?: Bindings;
27
+ }
@@ -0,0 +1,259 @@
1
+ <!--
2
+ CommandConsole Component
3
+ Bottom-panel REPL shell for the FlowDrop Command DSL
4
+ Styled with BEM syntax matching ConfigPanel pattern
5
+ -->
6
+
7
+ <script lang="ts">
8
+ import type { NodeMetadata } from "../../types/index.js";
9
+ import {
10
+ parseCommand,
11
+ executeCommand,
12
+ executeBatch,
13
+ type UIAction,
14
+ type CommandContext,
15
+ type CommandResultOk,
16
+ type ListNodesResultData,
17
+ type ListEdgesResultData,
18
+ type ListTypesResultData,
19
+ type InfoResultData,
20
+ type HelpResultData,
21
+ } from "../../commands/index.js";
22
+ import { createStoreCommandContext } from "../../commands/storeIntegration.svelte.js";
23
+ import { updateSettings, getUiSettings } from "../../stores/settingsStore.svelte.js";
24
+ import ConsoleInput from "./ConsoleInput.svelte";
25
+ import ConsoleOutput, { type ConsoleEntry } from "./ConsoleOutput.svelte";
26
+ import {
27
+ formatListNodes,
28
+ formatListEdges,
29
+ formatListTypes,
30
+ formatInfo,
31
+ formatHelp,
32
+ } from "./formatters.js";
33
+
34
+ interface Props {
35
+ /** Available node types for command execution */
36
+ nodeTypes: NodeMetadata[];
37
+ /** Callback for UI actions (open config, select node) */
38
+ onUIAction?: (action: UIAction) => void;
39
+ }
40
+
41
+ let { nodeTypes, onUIAction }: Props = $props();
42
+
43
+ let outputEntries: ConsoleEntry[] = $state([]);
44
+ let commandContext: CommandContext | null = $state(null);
45
+
46
+ // Recreate context when nodeTypes changes
47
+ $effect(() => {
48
+ commandContext = createStoreCommandContext(nodeTypes, onUIAction);
49
+ });
50
+
51
+ /**
52
+ * Attempts to format CommandResult data into a rich display string.
53
+ * Returns null if the result has no formattable data.
54
+ */
55
+ function formatResultData(commandType: string, result: CommandResultOk): string | null {
56
+ if (!result.data) return null;
57
+
58
+ switch (commandType) {
59
+ case "list_nodes":
60
+ return formatListNodes(result.data as ListNodesResultData);
61
+ case "list_edges":
62
+ return formatListEdges(result.data as ListEdgesResultData);
63
+ case "list_types":
64
+ return formatListTypes(result.data as ListTypesResultData);
65
+ case "info":
66
+ return formatInfo(result.data as InfoResultData);
67
+ case "help":
68
+ return formatHelp(result.data as HelpResultData);
69
+ default:
70
+ return null;
71
+ }
72
+ }
73
+
74
+ function closeConsole() {
75
+ updateSettings({ ui: { consoleOpen: false } });
76
+ }
77
+
78
+ function handleCommandSubmit(value: string) {
79
+ const trimmed = value.trim();
80
+ if (!trimmed) return;
81
+
82
+ // Add the input entry to the output
83
+ outputEntries.push({ type: "input", text: trimmed });
84
+
85
+ // Handle cls command (clear console output; use 'clear' to clear the canvas)
86
+ if (trimmed.toLowerCase() === "cls") {
87
+ outputEntries = [];
88
+ return;
89
+ }
90
+
91
+ // Parse the command
92
+ const parseResult = parseCommand(trimmed);
93
+ if (!parseResult.ok) {
94
+ outputEntries.push({ type: "error", text: parseResult.error });
95
+ return;
96
+ }
97
+
98
+ // Ensure we have a command context
99
+ if (!commandContext) {
100
+ outputEntries.push({ type: "error", text: "No workflow loaded" });
101
+ return;
102
+ }
103
+
104
+ // Execute the command
105
+ const result = executeCommand(parseResult.command, commandContext);
106
+ if (result.ok) {
107
+ const formatted = formatResultData(parseResult.command.type, result);
108
+ if (formatted) {
109
+ outputEntries.push({ type: "formatted", text: formatted });
110
+ } else {
111
+ outputEntries.push({ type: "success", text: result.message });
112
+ }
113
+ } else {
114
+ outputEntries.push({ type: "error", text: result.error });
115
+ }
116
+ }
117
+
118
+ function handleBatchSubmit(lines: string[]) {
119
+ if (!commandContext) {
120
+ outputEntries.push({ type: "error", text: "No workflow loaded" });
121
+ return;
122
+ }
123
+
124
+ const totalCount = lines.length;
125
+
126
+ // Parse all commands first
127
+ const parsed: { line: string; command?: import("../../commands/index.js").Command; error?: string }[] = [];
128
+ for (const line of lines) {
129
+ outputEntries.push({ type: "input", text: line });
130
+
131
+ if (line.toLowerCase() === "cls") {
132
+ outputEntries = [];
133
+ parsed.length = 0;
134
+ continue;
135
+ }
136
+
137
+ const parseResult = parseCommand(line);
138
+ if (!parseResult.ok) {
139
+ outputEntries.push({ type: "error", text: parseResult.error });
140
+ const succeeded = parsed.length;
141
+ outputEntries.push({
142
+ type: "error",
143
+ text: `Batch failed at command ${succeeded + 1}/${totalCount}: parse error`,
144
+ });
145
+ return;
146
+ }
147
+ parsed.push({ line, command: parseResult.command });
148
+ }
149
+
150
+ if (parsed.length === 0) return;
151
+
152
+ const commands = parsed.map((p) => p.command!);
153
+ const batchResult = executeBatch(commands, commandContext);
154
+
155
+ // Show individual results
156
+ for (let i = 0; i < batchResult.results.length; i++) {
157
+ const result = batchResult.results[i];
158
+ if (result.ok) {
159
+ const formatted = formatResultData(commands[i].type, result);
160
+ if (formatted) {
161
+ outputEntries.push({ type: "formatted", text: formatted });
162
+ } else {
163
+ outputEntries.push({ type: "success", text: result.message });
164
+ }
165
+ } else {
166
+ outputEntries.push({ type: "error", text: result.error });
167
+ }
168
+ }
169
+
170
+ // Show summary
171
+ if (batchResult.ok) {
172
+ outputEntries.push({
173
+ type: "success",
174
+ text: `Batch: ${batchResult.completedCount}/${batchResult.totalCount} commands succeeded`,
175
+ });
176
+ } else {
177
+ outputEntries.push({
178
+ type: "error",
179
+ text: `Batch failed at command ${batchResult.completedCount + 1}/${batchResult.totalCount}: ${batchResult.error}`,
180
+ });
181
+ }
182
+ }
183
+ </script>
184
+
185
+ <div class="command-console" role="region" aria-label="Command Console">
186
+ <div class="command-console__header">
187
+ <h2 class="command-console__title">Console</h2>
188
+ <button
189
+ class="command-console__close"
190
+ onclick={closeConsole}
191
+ aria-label="Close console"
192
+ type="button"
193
+ >
194
+ &times;
195
+ </button>
196
+ </div>
197
+ <div class="command-console__content">
198
+ <ConsoleOutput entries={outputEntries} />
199
+ </div>
200
+ <ConsoleInput
201
+ open={getUiSettings().consoleOpen}
202
+ {nodeTypes}
203
+ onSubmit={handleCommandSubmit}
204
+ onBatchSubmit={handleBatchSubmit}
205
+ onClose={closeConsole}
206
+ />
207
+ </div>
208
+
209
+ <style>
210
+ .command-console {
211
+ height: 100%;
212
+ display: flex;
213
+ flex-direction: column;
214
+ background-color: var(--fd-background);
215
+ }
216
+
217
+ .command-console__header {
218
+ display: flex;
219
+ justify-content: space-between;
220
+ align-items: center;
221
+ padding: 0.5rem 1rem;
222
+ border-bottom: 1px solid var(--fd-border);
223
+ background-color: var(--fd-muted);
224
+ flex-shrink: 0;
225
+ }
226
+
227
+ .command-console__title {
228
+ margin: 0;
229
+ font-size: 0.875rem;
230
+ font-weight: 600;
231
+ color: var(--fd-foreground);
232
+ }
233
+
234
+ .command-console__close {
235
+ background: none;
236
+ border: none;
237
+ font-size: 1.25rem;
238
+ line-height: 1;
239
+ cursor: pointer;
240
+ color: var(--fd-muted-foreground);
241
+ padding: 0.25rem;
242
+ border-radius: var(--fd-radius-sm);
243
+ transition:
244
+ color var(--fd-transition-fast),
245
+ background-color var(--fd-transition-fast);
246
+ }
247
+
248
+ .command-console__close:hover {
249
+ color: var(--fd-foreground);
250
+ background-color: var(--fd-subtle);
251
+ }
252
+
253
+ .command-console__content {
254
+ flex: 1;
255
+ overflow: hidden;
256
+ display: flex;
257
+ flex-direction: column;
258
+ }
259
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { NodeMetadata } from "../../types/index.js";
2
+ import { type UIAction } from "../../commands/index.js";
3
+ interface Props {
4
+ /** Available node types for command execution */
5
+ nodeTypes: NodeMetadata[];
6
+ /** Callback for UI actions (open config, select node) */
7
+ onUIAction?: (action: UIAction) => void;
8
+ }
9
+ declare const CommandConsole: import("svelte").Component<Props, {}, "">;
10
+ type CommandConsole = ReturnType<typeof CommandConsole>;
11
+ export default CommandConsole;