@d34dman/flowdrop 0.0.56 → 0.0.58

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 (83) hide show
  1. package/README.md +4 -4
  2. package/dist/adapters/WorkflowAdapter.d.ts +2 -1
  3. package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +96 -0
  4. package/dist/adapters/agentspec/AgentSpecAdapter.js +663 -0
  5. package/dist/adapters/agentspec/agentAdapter.d.ts +59 -0
  6. package/dist/adapters/agentspec/agentAdapter.js +91 -0
  7. package/dist/adapters/agentspec/autoLayout.d.ts +34 -0
  8. package/dist/adapters/agentspec/autoLayout.js +127 -0
  9. package/dist/adapters/agentspec/componentTypeDefaults.d.ts +73 -0
  10. package/dist/adapters/agentspec/componentTypeDefaults.js +238 -0
  11. package/dist/adapters/agentspec/defaultNodeTypes.d.ts +53 -0
  12. package/dist/adapters/agentspec/defaultNodeTypes.js +561 -0
  13. package/dist/adapters/agentspec/index.d.ts +37 -0
  14. package/dist/adapters/agentspec/index.js +39 -0
  15. package/dist/adapters/agentspec/validator.d.ts +34 -0
  16. package/dist/adapters/agentspec/validator.js +169 -0
  17. package/dist/components/App.svelte +57 -13
  18. package/dist/components/ConfigForm.svelte +46 -12
  19. package/dist/components/ConfigForm.svelte.d.ts +8 -0
  20. package/dist/components/NodeSidebar.svelte +20 -8
  21. package/dist/components/NodeSidebar.svelte.d.ts +2 -1
  22. package/dist/components/SchemaForm.svelte +34 -12
  23. package/dist/components/SchemaForm.svelte.d.ts +8 -0
  24. package/dist/components/WorkflowEditor.svelte +14 -13
  25. package/dist/components/form/FormFieldset.svelte +142 -0
  26. package/dist/components/form/FormFieldset.svelte.d.ts +11 -0
  27. package/dist/components/form/FormMarkdownEditor.svelte +546 -422
  28. package/dist/components/form/FormMarkdownEditor.svelte.d.ts +2 -0
  29. package/dist/components/form/FormUISchemaRenderer.svelte +136 -0
  30. package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +32 -0
  31. package/dist/components/form/index.d.ts +2 -0
  32. package/dist/components/form/index.js +3 -0
  33. package/dist/components/form/types.d.ts +1 -1
  34. package/dist/components/nodes/WorkflowNode.svelte +1 -2
  35. package/dist/config/agentSpecEndpoints.d.ts +70 -0
  36. package/dist/config/agentSpecEndpoints.js +65 -0
  37. package/dist/config/endpoints.d.ts +6 -0
  38. package/dist/core/index.d.ts +29 -3
  39. package/dist/core/index.js +31 -1
  40. package/dist/form/code.js +6 -1
  41. package/dist/form/fieldRegistry.d.ts +79 -15
  42. package/dist/form/fieldRegistry.js +104 -49
  43. package/dist/form/full.d.ts +2 -2
  44. package/dist/form/full.js +2 -2
  45. package/dist/form/index.d.ts +5 -3
  46. package/dist/form/index.js +9 -2
  47. package/dist/form/markdown.d.ts +3 -3
  48. package/dist/form/markdown.js +8 -4
  49. package/dist/helpers/workflowEditorHelper.d.ts +24 -0
  50. package/dist/helpers/workflowEditorHelper.js +55 -0
  51. package/dist/index.d.ts +2 -2
  52. package/dist/index.js +2 -2
  53. package/dist/registry/BaseRegistry.d.ts +92 -0
  54. package/dist/registry/BaseRegistry.js +124 -0
  55. package/dist/registry/builtinFormats.d.ts +23 -0
  56. package/dist/registry/builtinFormats.js +70 -0
  57. package/dist/registry/builtinNodes.js +4 -0
  58. package/dist/registry/index.d.ts +2 -1
  59. package/dist/registry/index.js +2 -0
  60. package/dist/registry/nodeComponentRegistry.d.ts +26 -57
  61. package/dist/registry/nodeComponentRegistry.js +29 -82
  62. package/dist/registry/workflowFormatRegistry.d.ts +122 -0
  63. package/dist/registry/workflowFormatRegistry.js +96 -0
  64. package/dist/schema/index.d.ts +23 -0
  65. package/dist/schema/index.js +23 -0
  66. package/dist/services/agentSpecExecutionService.d.ts +106 -0
  67. package/dist/services/agentSpecExecutionService.js +333 -0
  68. package/dist/stores/portCoordinateStore.js +1 -4
  69. package/dist/stores/workflowStore.d.ts +3 -0
  70. package/dist/stores/workflowStore.js +3 -0
  71. package/dist/svelte-app.d.ts +4 -0
  72. package/dist/svelte-app.js +9 -1
  73. package/dist/types/agentspec.d.ts +318 -0
  74. package/dist/types/agentspec.js +48 -0
  75. package/dist/types/events.d.ts +28 -1
  76. package/dist/types/index.d.ts +31 -0
  77. package/dist/types/index.js +5 -0
  78. package/dist/types/uischema.d.ts +144 -0
  79. package/dist/types/uischema.js +51 -0
  80. package/dist/utils/uischema.d.ts +52 -0
  81. package/dist/utils/uischema.js +88 -0
  82. package/package.json +231 -225
  83. package/schemas/v1/workflow.schema.json +952 -0
@@ -6,9 +6,11 @@
6
6
  * - Dynamic field types: Users can add custom field renderers
7
7
  * - Lazy loading: Components can be registered at runtime
8
8
  *
9
+ * Extends BaseRegistry for shared mechanics (subscribe, onClear, etc.).
10
+ *
9
11
  * @module form/fieldRegistry
10
12
  *
11
- * @example Basic usage with light fields only (no codemirror/easymde):
13
+ * @example Basic usage with light fields only (no codemirror):
12
14
  * ```typescript
13
15
  * import { SchemaForm } from "@d34dman/flowdrop/form";
14
16
  * // Uses only basic fields - small bundle size
@@ -24,6 +26,7 @@
24
26
  */
25
27
  import type { Component } from 'svelte';
26
28
  import type { FieldSchema } from '../components/form/types.js';
29
+ import { BaseRegistry } from '../registry/BaseRegistry.js';
27
30
  /**
28
31
  * Base field component props that all registered field components should accept.
29
32
  * Components may have additional specific props.
@@ -54,18 +57,65 @@ export type FieldMatcher = (schema: FieldSchema) => boolean;
54
57
  */
55
58
  export type FieldComponent = Component<any, any, any>;
56
59
  /**
57
- * Registration entry for a field component
60
+ * Framework-agnostic matcher registration (no Svelte dependency).
61
+ * Contains the matching logic and priority without the component.
58
62
  */
59
- export interface FieldComponentRegistration {
60
- /** The Svelte component to render */
61
- component: FieldComponent;
62
- /** Function to determine if this component should handle a given schema */
63
+ export interface FieldMatcherRegistration {
64
+ /** Function to determine if this registration should handle a given schema */
63
65
  matcher: FieldMatcher;
64
66
  /** Priority for matching (higher = checked first) */
65
67
  priority: number;
66
68
  }
67
69
  /**
68
- * Register a field component for a specific field type
70
+ * Full registration entry for a field component.
71
+ * Extends FieldMatcherRegistration with the Svelte component needed for rendering.
72
+ */
73
+ export interface FieldComponentRegistration extends FieldMatcherRegistration {
74
+ /** The Svelte component to render */
75
+ component: FieldComponent;
76
+ }
77
+ /**
78
+ * Class-based field component registry.
79
+ * Extends BaseRegistry with priority-based field resolution.
80
+ */
81
+ declare class FieldComponentRegistry extends BaseRegistry<string, FieldComponentRegistration> {
82
+ /** Cached ordered keys by priority (highest first), invalidated on mutation */
83
+ private orderedKeys;
84
+ /**
85
+ * Register a field component.
86
+ * Silently overwrites existing registrations (preserves legacy behavior).
87
+ *
88
+ * @param type - Unique identifier for this field type
89
+ * @param registration - The field component registration
90
+ */
91
+ register(type: string, registration: FieldComponentRegistration): void;
92
+ /**
93
+ * Override unregister to invalidate the priority cache.
94
+ */
95
+ unregister(key: string): boolean;
96
+ /**
97
+ * Override clear to invalidate the priority cache.
98
+ */
99
+ clear(): void;
100
+ /**
101
+ * Resolve which component should render a given field schema.
102
+ * Checks registered matchers in priority order (highest first).
103
+ *
104
+ * @param schema - The field schema to resolve
105
+ * @returns The matching registration or null if no match
106
+ */
107
+ resolveFieldComponent(schema: FieldSchema): FieldComponentRegistration | null;
108
+ /**
109
+ * Get keys ordered by priority (cached).
110
+ */
111
+ private getOrderedKeys;
112
+ }
113
+ /** Singleton instance of the field component registry */
114
+ export declare const fieldComponentRegistry: FieldComponentRegistry;
115
+ /**
116
+ * Register a field component for a specific field type.
117
+ *
118
+ * @deprecated Use `fieldComponentRegistry.register()` instead.
69
119
  *
70
120
  * @param type - Unique identifier for this field type
71
121
  * @param component - Svelte component to render for matching fields
@@ -84,40 +134,53 @@ export interface FieldComponentRegistration {
84
134
  */
85
135
  export declare function registerFieldComponent(type: string, component: FieldComponent, matcher: FieldMatcher, priority?: number): void;
86
136
  /**
87
- * Unregister a field component
137
+ * Unregister a field component.
138
+ *
139
+ * @deprecated Use `fieldComponentRegistry.unregister()` instead.
88
140
  *
89
141
  * @param type - The field type to unregister
90
142
  * @returns true if the component was registered and removed
91
143
  */
92
144
  export declare function unregisterFieldComponent(type: string): boolean;
93
145
  /**
94
- * Get all registered field types
146
+ * Get all registered field types.
147
+ *
148
+ * @deprecated Use `fieldComponentRegistry.getKeys()` instead.
95
149
  *
96
150
  * @returns Array of registered field type identifiers
97
151
  */
98
152
  export declare function getRegisteredFieldTypes(): string[];
99
153
  /**
100
- * Check if a field type is registered
154
+ * Check if a field type is registered.
155
+ *
156
+ * @deprecated Use `fieldComponentRegistry.has()` instead.
101
157
  *
102
158
  * @param type - Field type to check
103
159
  * @returns true if the type is registered
104
160
  */
105
161
  export declare function isFieldTypeRegistered(type: string): boolean;
106
162
  /**
107
- * Resolve which component should render a given field schema
108
- * Checks registered matchers in priority order
163
+ * Resolve which component should render a given field schema.
164
+ * Checks registered matchers in priority order.
165
+ *
166
+ * @deprecated Use `fieldComponentRegistry.resolveFieldComponent()` instead.
109
167
  *
110
168
  * @param schema - The field schema to resolve
111
169
  * @returns The matching registration or null if no match
112
170
  */
113
171
  export declare function resolveFieldComponent(schema: FieldSchema): FieldComponentRegistration | null;
114
172
  /**
115
- * Clear all registered field components
116
- * Useful for testing or reset scenarios
173
+ * Clear all registered field components.
174
+ * Useful for testing or reset scenarios.
175
+ *
176
+ * @deprecated Use `fieldComponentRegistry.clear()` instead.
117
177
  */
118
178
  export declare function clearFieldRegistry(): void;
119
179
  /**
120
- * Get the registry size
180
+ * Get the registry size.
181
+ *
182
+ * @deprecated Use `fieldComponentRegistry.size` instead.
183
+ *
121
184
  * @returns Number of registered field components
122
185
  */
123
186
  export declare function getFieldRegistrySize(): number;
@@ -177,3 +240,4 @@ export declare const arrayMatcher: FieldMatcher;
177
240
  * Matches when format is "autocomplete" and autocomplete config with URL is provided
178
241
  */
179
242
  export declare const autocompleteMatcher: FieldMatcher;
243
+ export {};
@@ -6,9 +6,11 @@
6
6
  * - Dynamic field types: Users can add custom field renderers
7
7
  * - Lazy loading: Components can be registered at runtime
8
8
  *
9
+ * Extends BaseRegistry for shared mechanics (subscribe, onClear, etc.).
10
+ *
9
11
  * @module form/fieldRegistry
10
12
  *
11
- * @example Basic usage with light fields only (no codemirror/easymde):
13
+ * @example Basic usage with light fields only (no codemirror):
12
14
  * ```typescript
13
15
  * import { SchemaForm } from "@d34dman/flowdrop/form";
14
16
  * // Uses only basic fields - small bundle size
@@ -22,18 +24,82 @@
22
24
  * registerFieldComponent("code-editor", FormCodeEditor, codeEditorFieldMatcher);
23
25
  * ```
24
26
  */
27
+ import { BaseRegistry } from '../registry/BaseRegistry.js';
25
28
  /**
26
- * Field component registry
27
- * Stores registered field components with their matchers
28
- */
29
- const fieldRegistry = new Map();
30
- /**
31
- * Ordered list of field type keys by priority (highest first)
32
- * Cached and invalidated when registry changes
29
+ * Class-based field component registry.
30
+ * Extends BaseRegistry with priority-based field resolution.
33
31
  */
34
- let orderedKeys = null;
32
+ class FieldComponentRegistry extends BaseRegistry {
33
+ /** Cached ordered keys by priority (highest first), invalidated on mutation */
34
+ orderedKeys = null;
35
+ /**
36
+ * Register a field component.
37
+ * Silently overwrites existing registrations (preserves legacy behavior).
38
+ *
39
+ * @param type - Unique identifier for this field type
40
+ * @param registration - The field component registration
41
+ */
42
+ register(type, registration) {
43
+ this.items.set(type, registration);
44
+ this.orderedKeys = null;
45
+ this.notifyListeners();
46
+ }
47
+ /**
48
+ * Override unregister to invalidate the priority cache.
49
+ */
50
+ unregister(key) {
51
+ const result = super.unregister(key);
52
+ if (result) {
53
+ this.orderedKeys = null;
54
+ }
55
+ return result;
56
+ }
57
+ /**
58
+ * Override clear to invalidate the priority cache.
59
+ */
60
+ clear() {
61
+ super.clear();
62
+ this.orderedKeys = null;
63
+ }
64
+ /**
65
+ * Resolve which component should render a given field schema.
66
+ * Checks registered matchers in priority order (highest first).
67
+ *
68
+ * @param schema - The field schema to resolve
69
+ * @returns The matching registration or null if no match
70
+ */
71
+ resolveFieldComponent(schema) {
72
+ const keys = this.getOrderedKeys();
73
+ for (const key of keys) {
74
+ const registration = this.items.get(key);
75
+ if (registration && registration.matcher(schema)) {
76
+ return registration;
77
+ }
78
+ }
79
+ return null;
80
+ }
81
+ /**
82
+ * Get keys ordered by priority (cached).
83
+ */
84
+ getOrderedKeys() {
85
+ if (this.orderedKeys === null) {
86
+ this.orderedKeys = Array.from(this.items.entries())
87
+ .sort((a, b) => b[1].priority - a[1].priority)
88
+ .map(([key]) => key);
89
+ }
90
+ return this.orderedKeys;
91
+ }
92
+ }
93
+ /** Singleton instance of the field component registry */
94
+ export const fieldComponentRegistry = new FieldComponentRegistry();
95
+ // ============================================================================
96
+ // Backward-compatible function exports
97
+ // These delegate to the singleton and preserve the existing public API.
98
+ // ============================================================================
35
99
  /**
36
- * Register a field component for a specific field type
100
+ * Register a field component for a specific field type.
101
+ *
102
+ * @deprecated Use `fieldComponentRegistry.register()` instead.
37
103
  *
38
104
  * @param type - Unique identifier for this field type
39
105
  * @param component - Svelte component to render for matching fields
@@ -51,81 +117,70 @@ let orderedKeys = null;
51
117
  * ```
52
118
  */
53
119
  export function registerFieldComponent(type, component, matcher, priority = 0) {
54
- fieldRegistry.set(type, { component, matcher, priority });
55
- orderedKeys = null; // Invalidate cache
120
+ fieldComponentRegistry.register(type, { component, matcher, priority });
56
121
  }
57
122
  /**
58
- * Unregister a field component
123
+ * Unregister a field component.
124
+ *
125
+ * @deprecated Use `fieldComponentRegistry.unregister()` instead.
59
126
  *
60
127
  * @param type - The field type to unregister
61
128
  * @returns true if the component was registered and removed
62
129
  */
63
130
  export function unregisterFieldComponent(type) {
64
- const removed = fieldRegistry.delete(type);
65
- if (removed) {
66
- orderedKeys = null; // Invalidate cache
67
- }
68
- return removed;
131
+ return fieldComponentRegistry.unregister(type);
69
132
  }
70
133
  /**
71
- * Get all registered field types
134
+ * Get all registered field types.
135
+ *
136
+ * @deprecated Use `fieldComponentRegistry.getKeys()` instead.
72
137
  *
73
138
  * @returns Array of registered field type identifiers
74
139
  */
75
140
  export function getRegisteredFieldTypes() {
76
- return Array.from(fieldRegistry.keys());
141
+ return fieldComponentRegistry.getKeys();
77
142
  }
78
143
  /**
79
- * Check if a field type is registered
144
+ * Check if a field type is registered.
145
+ *
146
+ * @deprecated Use `fieldComponentRegistry.has()` instead.
80
147
  *
81
148
  * @param type - Field type to check
82
149
  * @returns true if the type is registered
83
150
  */
84
151
  export function isFieldTypeRegistered(type) {
85
- return fieldRegistry.has(type);
86
- }
87
- /**
88
- * Get ordered keys by priority (cached)
89
- */
90
- function getOrderedKeys() {
91
- if (orderedKeys === null) {
92
- orderedKeys = Array.from(fieldRegistry.entries())
93
- .sort((a, b) => b[1].priority - a[1].priority)
94
- .map(([key]) => key);
95
- }
96
- return orderedKeys;
152
+ return fieldComponentRegistry.has(type);
97
153
  }
98
154
  /**
99
- * Resolve which component should render a given field schema
100
- * Checks registered matchers in priority order
155
+ * Resolve which component should render a given field schema.
156
+ * Checks registered matchers in priority order.
157
+ *
158
+ * @deprecated Use `fieldComponentRegistry.resolveFieldComponent()` instead.
101
159
  *
102
160
  * @param schema - The field schema to resolve
103
161
  * @returns The matching registration or null if no match
104
162
  */
105
163
  export function resolveFieldComponent(schema) {
106
- const keys = getOrderedKeys();
107
- for (const key of keys) {
108
- const registration = fieldRegistry.get(key);
109
- if (registration && registration.matcher(schema)) {
110
- return registration;
111
- }
112
- }
113
- return null;
164
+ return fieldComponentRegistry.resolveFieldComponent(schema);
114
165
  }
115
166
  /**
116
- * Clear all registered field components
117
- * Useful for testing or reset scenarios
167
+ * Clear all registered field components.
168
+ * Useful for testing or reset scenarios.
169
+ *
170
+ * @deprecated Use `fieldComponentRegistry.clear()` instead.
118
171
  */
119
172
  export function clearFieldRegistry() {
120
- fieldRegistry.clear();
121
- orderedKeys = null;
173
+ fieldComponentRegistry.clear();
122
174
  }
123
175
  /**
124
- * Get the registry size
176
+ * Get the registry size.
177
+ *
178
+ * @deprecated Use `fieldComponentRegistry.size` instead.
179
+ *
125
180
  * @returns Number of registered field components
126
181
  */
127
182
  export function getFieldRegistrySize() {
128
- return fieldRegistry.size;
183
+ return fieldComponentRegistry.size;
129
184
  }
130
185
  // ============================================================================
131
186
  // Built-in Field Matchers (for light fields)
@@ -2,7 +2,7 @@
2
2
  * FlowDrop Form Full Module
3
3
  *
4
4
  * Convenience module that imports and registers all form field types,
5
- * including heavy editors (CodeMirror, EasyMDE).
5
+ * including heavy editors (CodeMirror).
6
6
  *
7
7
  * This is equivalent to importing from the light form module and manually
8
8
  * registering all editor types.
@@ -32,7 +32,7 @@ export { registerMarkdownEditorField, isMarkdownEditorRegistered, markdownEditor
32
32
  * This includes:
33
33
  * - Code/JSON editor (CodeMirror)
34
34
  * - Template editor (CodeMirror with Twig/Liquid syntax)
35
- * - Markdown editor (EasyMDE)
35
+ * - Markdown editor (CodeMirror 6)
36
36
  *
37
37
  * @example
38
38
  * ```typescript
package/dist/form/full.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * FlowDrop Form Full Module
3
3
  *
4
4
  * Convenience module that imports and registers all form field types,
5
- * including heavy editors (CodeMirror, EasyMDE).
5
+ * including heavy editors (CodeMirror).
6
6
  *
7
7
  * This is equivalent to importing from the light form module and manually
8
8
  * registering all editor types.
@@ -42,7 +42,7 @@ let allFieldTypesInitialized = false;
42
42
  * This includes:
43
43
  * - Code/JSON editor (CodeMirror)
44
44
  * - Template editor (CodeMirror with Twig/Liquid syntax)
45
- * - Markdown editor (EasyMDE)
45
+ * - Markdown editor (CodeMirror 6)
46
46
  *
47
47
  * @example
48
48
  * ```typescript
@@ -6,7 +6,7 @@
6
6
  * only basic field types (text, number, select, checkbox, etc.).
7
7
  *
8
8
  * For code editor support (CodeMirror), import from "@d34dman/flowdrop/form/code"
9
- * For markdown editor support (EasyMDE), import from "@d34dman/flowdrop/form/markdown"
9
+ * For markdown editor support (CodeMirror 6), import from "@d34dman/flowdrop/form/markdown"
10
10
  *
11
11
  * @module form
12
12
  *
@@ -69,7 +69,9 @@ export { default as FormToggle } from '../components/form/FormToggle.svelte';
69
69
  export { default as FormSelect } from '../components/form/FormSelect.svelte';
70
70
  export { default as FormCheckboxGroup } from '../components/form/FormCheckboxGroup.svelte';
71
71
  export { default as FormArray } from '../components/form/FormArray.svelte';
72
+ export { default as FormFieldset } from '../components/form/FormFieldset.svelte';
73
+ export { default as FormUISchemaRenderer } from '../components/form/FormUISchemaRenderer.svelte';
72
74
  export type { FieldSchema, FieldType, FieldFormat, FieldOption, OneOfItem, SchemaFormProps, BaseFieldProps, TextFieldProps, TextareaFieldProps, NumberFieldProps, ToggleFieldProps, RangeFieldProps, SelectFieldProps, CheckboxGroupFieldProps, ArrayFieldProps, FormFieldFactoryProps, FormFieldWrapperProps } from '../components/form/types.js';
73
75
  export { isFieldOptionArray, isOneOfArray, normalizeOptions, oneOfToOptions, getSchemaOptions } from '../components/form/types.js';
74
- export { registerFieldComponent, unregisterFieldComponent, resolveFieldComponent, getRegisteredFieldTypes, isFieldTypeRegistered, clearFieldRegistry, getFieldRegistrySize, hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
75
- export type { FieldComponentProps, FieldMatcher, FieldComponent, FieldComponentRegistration } from './fieldRegistry.js';
76
+ export { fieldComponentRegistry, registerFieldComponent, unregisterFieldComponent, resolveFieldComponent, getRegisteredFieldTypes, isFieldTypeRegistered, clearFieldRegistry, getFieldRegistrySize, hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
77
+ export type { FieldComponentProps, FieldMatcher, FieldMatcherRegistration, FieldComponent, FieldComponentRegistration } from './fieldRegistry.js';
@@ -6,7 +6,7 @@
6
6
  * only basic field types (text, number, select, checkbox, etc.).
7
7
  *
8
8
  * For code editor support (CodeMirror), import from "@d34dman/flowdrop/form/code"
9
- * For markdown editor support (EasyMDE), import from "@d34dman/flowdrop/form/markdown"
9
+ * For markdown editor support (CodeMirror 6), import from "@d34dman/flowdrop/form/markdown"
10
10
  *
11
11
  * @module form
12
12
  *
@@ -77,10 +77,17 @@ export { default as FormToggle } from '../components/form/FormToggle.svelte';
77
77
  export { default as FormSelect } from '../components/form/FormSelect.svelte';
78
78
  export { default as FormCheckboxGroup } from '../components/form/FormCheckboxGroup.svelte';
79
79
  export { default as FormArray } from '../components/form/FormArray.svelte';
80
+ // UISchema rendering components
81
+ export { default as FormFieldset } from '../components/form/FormFieldset.svelte';
82
+ export { default as FormUISchemaRenderer } from '../components/form/FormUISchemaRenderer.svelte';
80
83
  export { isFieldOptionArray, isOneOfArray, normalizeOptions, oneOfToOptions, getSchemaOptions } from '../components/form/types.js';
81
84
  // ============================================================================
82
85
  // Field Registry (for dynamic field registration)
83
86
  // ============================================================================
84
- export { registerFieldComponent, unregisterFieldComponent, resolveFieldComponent, getRegisteredFieldTypes, isFieldTypeRegistered, clearFieldRegistry, getFieldRegistrySize,
87
+ export {
88
+ // Registry singleton
89
+ fieldComponentRegistry,
90
+ // Backward-compatible function wrappers
91
+ registerFieldComponent, unregisterFieldComponent, resolveFieldComponent, getRegisteredFieldTypes, isFieldTypeRegistered, clearFieldRegistry, getFieldRegistrySize,
85
92
  // Built-in matchers for custom components
86
93
  hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * FlowDrop Form Markdown Editor Module
3
3
  *
4
- * Adds EasyMDE-based markdown editor support to SchemaForm.
5
- * This module bundles EasyMDE dependencies (~200KB).
4
+ * Adds CodeMirror 6-based markdown editor support to SchemaForm.
5
+ * Uses @codemirror/lang-markdown for syntax highlighting and marked for preview.
6
6
  *
7
7
  * @module form/markdown
8
8
  *
@@ -35,7 +35,7 @@ export declare function markdownEditorFieldMatcher(schema: FieldSchema): boolean
35
35
  * Register the markdown editor field component
36
36
  *
37
37
  * Call this function once at application startup to enable
38
- * markdown editor fields in SchemaForm. This loads EasyMDE dependencies.
38
+ * markdown editor fields in SchemaForm.
39
39
  *
40
40
  * @param priority - Priority for field matching (default: 100)
41
41
  *
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * FlowDrop Form Markdown Editor Module
3
3
  *
4
- * Adds EasyMDE-based markdown editor support to SchemaForm.
5
- * This module bundles EasyMDE dependencies (~200KB).
4
+ * Adds CodeMirror 6-based markdown editor support to SchemaForm.
5
+ * Uses @codemirror/lang-markdown for syntax highlighting and marked for preview.
6
6
  *
7
7
  * @module form/markdown
8
8
  *
@@ -23,7 +23,7 @@
23
23
  * };
24
24
  * ```
25
25
  */
26
- import { registerFieldComponent } from './fieldRegistry.js';
26
+ import { registerFieldComponent, fieldComponentRegistry } from './fieldRegistry.js';
27
27
  // Re-export the component for direct usage if needed
28
28
  export { default as FormMarkdownEditor } from '../components/form/FormMarkdownEditor.svelte';
29
29
  /**
@@ -37,11 +37,15 @@ export function markdownEditorFieldMatcher(schema) {
37
37
  * Track if markdown editor is registered
38
38
  */
39
39
  let markdownEditorRegistered = false;
40
+ // Sync registration flag with registry.clear() for test isolation
41
+ fieldComponentRegistry.onClear(() => {
42
+ markdownEditorRegistered = false;
43
+ });
40
44
  /**
41
45
  * Register the markdown editor field component
42
46
  *
43
47
  * Call this function once at application startup to enable
44
- * markdown editor fields in SchemaForm. This loads EasyMDE dependencies.
48
+ * markdown editor fields in SchemaForm.
45
49
  *
46
50
  * @param priority - Priority for field matching (default: 100)
47
51
  *
@@ -131,6 +131,30 @@ export declare class WorkflowOperationsHelper {
131
131
  * Export workflow as JSON file
132
132
  */
133
133
  static exportWorkflow(workflow: Workflow | null): void;
134
+ /**
135
+ * Export workflow as Agent Spec JSON file.
136
+ *
137
+ * Converts the FlowDrop workflow to Agent Spec format and triggers a download.
138
+ * Validates the workflow for Agent Spec compatibility first.
139
+ *
140
+ * @param workflow - The FlowDrop workflow to export
141
+ * @returns Validation result (check .valid before assuming success)
142
+ */
143
+ static exportAsAgentSpec(workflow: Workflow | null): {
144
+ valid: boolean;
145
+ errors: string[];
146
+ warnings: string[];
147
+ };
148
+ /**
149
+ * Import a workflow from an Agent Spec JSON or YAML file.
150
+ *
151
+ * Reads the file, detects format, converts to FlowDrop format,
152
+ * and returns a Workflow ready for the editor.
153
+ *
154
+ * @param file - The file to import (JSON or YAML)
155
+ * @returns Promise resolving to the imported FlowDrop Workflow
156
+ */
157
+ static importFromAgentSpec(file: File): Promise<Workflow>;
134
158
  /**
135
159
  * Check if workflow has invalid cycles (excludes valid loopback cycles)
136
160
  * Valid loopback cycles are used for ForEach node iteration and should not
@@ -8,6 +8,9 @@ import { workflowApi, nodeApi, setEndpointConfig } from '../services/api.js';
8
8
  import { v4 as uuidv4 } from 'uuid';
9
9
  import { workflowActions } from '../stores/workflowStore.js';
10
10
  import { nodeExecutionService } from '../services/nodeExecutionService.js';
11
+ import { WorkflowAdapter } from '../adapters/WorkflowAdapter.js';
12
+ import { AgentSpecAdapter } from '../adapters/agentspec/AgentSpecAdapter.js';
13
+ import { validateForAgentSpecExport } from '../adapters/agentspec/validator.js';
11
14
  /**
12
15
  * Generate a unique node ID based on node type and existing nodes
13
16
  * Format: <node_type>.<number>
@@ -537,6 +540,58 @@ export class WorkflowOperationsHelper {
537
540
  link.click();
538
541
  URL.revokeObjectURL(url);
539
542
  }
543
+ /**
544
+ * Export workflow as Agent Spec JSON file.
545
+ *
546
+ * Converts the FlowDrop workflow to Agent Spec format and triggers a download.
547
+ * Validates the workflow for Agent Spec compatibility first.
548
+ *
549
+ * @param workflow - The FlowDrop workflow to export
550
+ * @returns Validation result (check .valid before assuming success)
551
+ */
552
+ static exportAsAgentSpec(workflow) {
553
+ if (!workflow) {
554
+ return { valid: false, errors: ['No workflow data available to export'], warnings: [] };
555
+ }
556
+ // Convert to StandardWorkflow first
557
+ const workflowAdapter = new WorkflowAdapter();
558
+ const standardWorkflow = workflowAdapter.fromSvelteFlow(workflow);
559
+ // Validate for Agent Spec
560
+ const validation = validateForAgentSpecExport(standardWorkflow);
561
+ if (!validation.valid) {
562
+ return validation;
563
+ }
564
+ // Convert to Agent Spec
565
+ const agentSpecAdapter = new AgentSpecAdapter();
566
+ const agentSpecJson = agentSpecAdapter.exportJSON(standardWorkflow);
567
+ // Trigger download
568
+ const dataBlob = new Blob([agentSpecJson], { type: 'application/json' });
569
+ const url = URL.createObjectURL(dataBlob);
570
+ const link = document.createElement('a');
571
+ link.href = url;
572
+ link.download = `${workflow.name || 'workflow'}-agentspec.json`;
573
+ link.click();
574
+ URL.revokeObjectURL(url);
575
+ return validation;
576
+ }
577
+ /**
578
+ * Import a workflow from an Agent Spec JSON or YAML file.
579
+ *
580
+ * Reads the file, detects format, converts to FlowDrop format,
581
+ * and returns a Workflow ready for the editor.
582
+ *
583
+ * @param file - The file to import (JSON or YAML)
584
+ * @returns Promise resolving to the imported FlowDrop Workflow
585
+ */
586
+ static async importFromAgentSpec(file) {
587
+ const text = await file.text();
588
+ const agentSpecAdapter = new AgentSpecAdapter();
589
+ const workflowAdapter = new WorkflowAdapter();
590
+ // Parse the Agent Spec data
591
+ const standardWorkflow = agentSpecAdapter.importJSON(text);
592
+ // Convert to SvelteFlow format
593
+ return workflowAdapter.toSvelteFlow(standardWorkflow);
594
+ }
540
595
  /**
541
596
  * Check if workflow has invalid cycles (excludes valid loopback cycles)
542
597
  * Valid loopback cycles are used for ForEach node iteration and should not
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * - `@d34dman/flowdrop/editor` - WorkflowEditor with @xyflow/svelte
12
12
  * - `@d34dman/flowdrop/form` - SchemaForm with basic fields
13
13
  * - `@d34dman/flowdrop/form/code` - Code editor support (adds CodeMirror)
14
- * - `@d34dman/flowdrop/form/markdown` - Markdown editor support (adds EasyMDE)
14
+ * - `@d34dman/flowdrop/form/markdown` - Markdown editor support (CodeMirror 6)
15
15
  * - `@d34dman/flowdrop/display` - MarkdownDisplay (adds marked)
16
16
  * - `@d34dman/flowdrop/playground` - Playground for interactive workflow testing
17
17
  * - `@d34dman/flowdrop/styles` - CSS styles
@@ -25,7 +25,7 @@
25
25
  * ```
26
26
  *
27
27
  * **Note**: This will bundle ALL dependencies including @xyflow/svelte,
28
- * CodeMirror, EasyMDE, and marked. For smaller bundles, use sub-modules.
28
+ * CodeMirror and marked. For smaller bundles, use sub-modules.
29
29
  *
30
30
  * @module flowdrop
31
31
  */
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@
11
11
  * - `@d34dman/flowdrop/editor` - WorkflowEditor with @xyflow/svelte
12
12
  * - `@d34dman/flowdrop/form` - SchemaForm with basic fields
13
13
  * - `@d34dman/flowdrop/form/code` - Code editor support (adds CodeMirror)
14
- * - `@d34dman/flowdrop/form/markdown` - Markdown editor support (adds EasyMDE)
14
+ * - `@d34dman/flowdrop/form/markdown` - Markdown editor support (CodeMirror 6)
15
15
  * - `@d34dman/flowdrop/display` - MarkdownDisplay (adds marked)
16
16
  * - `@d34dman/flowdrop/playground` - Playground for interactive workflow testing
17
17
  * - `@d34dman/flowdrop/styles` - CSS styles
@@ -25,7 +25,7 @@
25
25
  * ```
26
26
  *
27
27
  * **Note**: This will bundle ALL dependencies including @xyflow/svelte,
28
- * CodeMirror, EasyMDE, and marked. For smaller bundles, use sub-modules.
28
+ * CodeMirror and marked. For smaller bundles, use sub-modules.
29
29
  *
30
30
  * @module flowdrop
31
31
  */