@synergenius/flow-weaver 0.20.6 → 0.21.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.
- package/dist/api/command-runner.d.ts +13 -0
- package/dist/api/command-runner.js +217 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/cli/flow-weaver.mjs +24077 -38374
- package/dist/cli/index.js +0 -60
- package/dist/cli/templates/shared/llm-types.d.ts +1 -1
- package/dist/cli/templates/shared/llm-types.js +1 -1
- package/dist/cli/templates/workflows/foreach.js +1 -2
- package/dist/doc-metadata/extractors/cli-commands.js +37 -56
- package/dist/doc-metadata/extractors/mcp-tools.d.ts +1 -1
- package/dist/doc-metadata/extractors/mcp-tools.js +1 -213
- package/dist/doc-metadata/types.d.ts +2 -0
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +1 -1
- package/dist/generator/unified.js +25 -3
- package/dist/mcp/index.d.ts +1 -5
- package/dist/mcp/index.js +0 -4
- package/dist/mcp/server.js +3 -55
- package/dist/mcp/types.d.ts +0 -50
- package/dist/mcp/types.js +1 -7
- package/dist/mcp/workflow-executor.js +23 -1
- package/dist/parser.js +5 -1
- package/package.json +1 -2
- package/dist/cli/commands/listen.d.ts +0 -16
- package/dist/cli/commands/listen.js +0 -39
- package/dist/cli/commands/tunnel.d.ts +0 -19
- package/dist/cli/commands/tunnel.js +0 -119
- package/dist/cli/commands/ui.d.ts +0 -16
- package/dist/cli/commands/ui.js +0 -130
- package/dist/cli/tunnel/dispatch.d.ts +0 -18
- package/dist/cli/tunnel/dispatch.js +0 -36
- package/dist/cli/tunnel/file-lock.d.ts +0 -9
- package/dist/cli/tunnel/file-lock.js +0 -36
- package/dist/cli/tunnel/handlers/ast-ops.d.ts +0 -10
- package/dist/cli/tunnel/handlers/ast-ops.js +0 -252
- package/dist/cli/tunnel/handlers/execution.d.ts +0 -7
- package/dist/cli/tunnel/handlers/execution.js +0 -89
- package/dist/cli/tunnel/handlers/file-ops.d.ts +0 -7
- package/dist/cli/tunnel/handlers/file-ops.js +0 -204
- package/dist/cli/tunnel/handlers/mutations.d.ts +0 -7
- package/dist/cli/tunnel/handlers/mutations.js +0 -285
- package/dist/cli/tunnel/handlers/stubs.d.ts +0 -7
- package/dist/cli/tunnel/handlers/stubs.js +0 -143
- package/dist/cli/tunnel/handlers/templates.d.ts +0 -7
- package/dist/cli/tunnel/handlers/templates.js +0 -123
- package/dist/cli/tunnel/path-resolver.d.ts +0 -17
- package/dist/cli/tunnel/path-resolver.js +0 -54
- package/dist/defaults.d.ts +0 -3
- package/dist/defaults.js +0 -3
- package/dist/mcp/editor-connection.d.ts +0 -52
- package/dist/mcp/editor-connection.js +0 -142
- package/dist/mcp/event-buffer.d.ts +0 -62
- package/dist/mcp/event-buffer.js +0 -150
- package/dist/mcp/resources.d.ts +0 -14
- package/dist/mcp/resources.js +0 -55
- package/dist/mcp/tools-editor.d.ts +0 -5
- package/dist/mcp/tools-editor.js +0 -283
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic command runner for flow-weaver operations.
|
|
3
|
+
* Provides a unified dispatch interface that maps command names to
|
|
4
|
+
* the existing programmatic APIs, suitable for bot/agent consumption.
|
|
5
|
+
*/
|
|
6
|
+
export interface CommandResult {
|
|
7
|
+
output?: string;
|
|
8
|
+
files?: string[];
|
|
9
|
+
data?: unknown;
|
|
10
|
+
}
|
|
11
|
+
export declare function runCommand(name: string, args: Record<string, unknown>): Promise<CommandResult>;
|
|
12
|
+
export declare function getAvailableCommands(): string[];
|
|
13
|
+
//# sourceMappingURL=command-runner.d.ts.map
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic command runner for flow-weaver operations.
|
|
3
|
+
* Provides a unified dispatch interface that maps command names to
|
|
4
|
+
* the existing programmatic APIs, suitable for bot/agent consumption.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import { parseWorkflow } from './parse.js';
|
|
9
|
+
import { validateWorkflow } from './validate.js';
|
|
10
|
+
import { compileWorkflow } from './compile.js';
|
|
11
|
+
import { generateInPlace } from './generate-in-place.js';
|
|
12
|
+
import { applyModifyOperation, validateModifyParams } from './modify-operation.js';
|
|
13
|
+
import { generateWorkflowFromTemplate } from './templates.js';
|
|
14
|
+
import { getNodes, getConnections, getTopologicalOrder, findIsolatedNodes, findDeadEnds, countNodes, countConnections, } from './query.js';
|
|
15
|
+
import { WorkflowDiffer } from '../diff/WorkflowDiffer.js';
|
|
16
|
+
import { formatDiff } from '../diff/formatDiff.js';
|
|
17
|
+
function resolveFile(args, cwd) {
|
|
18
|
+
const file = String(args.file);
|
|
19
|
+
return cwd ? path.resolve(cwd, file) : path.resolve(file);
|
|
20
|
+
}
|
|
21
|
+
const handlers = {
|
|
22
|
+
compile: async (args) => {
|
|
23
|
+
const filePath = resolveFile(args, args.cwd);
|
|
24
|
+
await compileWorkflow(filePath);
|
|
25
|
+
return { files: [filePath] };
|
|
26
|
+
},
|
|
27
|
+
validate: async (args) => {
|
|
28
|
+
const filePath = resolveFile(args, args.cwd);
|
|
29
|
+
const parseResult = await parseWorkflow(filePath);
|
|
30
|
+
if (parseResult.errors.length > 0) {
|
|
31
|
+
return { data: { valid: false, errors: parseResult.errors, warnings: parseResult.warnings } };
|
|
32
|
+
}
|
|
33
|
+
const validation = validateWorkflow(parseResult.ast);
|
|
34
|
+
const errors = validation.errors.map((e) => typeof e === 'string' ? e : e.message);
|
|
35
|
+
const warnings = validation.warnings.map((w) => typeof w === 'string' ? w : w.message);
|
|
36
|
+
return { data: { valid: errors.length === 0, errors, warnings } };
|
|
37
|
+
},
|
|
38
|
+
describe: async (args) => {
|
|
39
|
+
const filePath = resolveFile(args, args.cwd);
|
|
40
|
+
const { describeWorkflow, formatTextOutput } = await import('../cli/commands/describe.js');
|
|
41
|
+
const parseResult = await parseWorkflow(filePath);
|
|
42
|
+
if (parseResult.errors.length > 0) {
|
|
43
|
+
throw new Error(`Parse errors:\n${parseResult.errors.join('\n')}`);
|
|
44
|
+
}
|
|
45
|
+
const output = describeWorkflow(parseResult.ast);
|
|
46
|
+
return { output: formatTextOutput(parseResult.ast, output) };
|
|
47
|
+
},
|
|
48
|
+
diagram: async (args) => {
|
|
49
|
+
const filePath = resolveFile(args, args.cwd);
|
|
50
|
+
const { fileToSVG, fileToASCII } = await import('../diagram/index.js');
|
|
51
|
+
const format = args.format ?? 'ascii';
|
|
52
|
+
const output = format === 'svg' ? fileToSVG(filePath) : fileToASCII(filePath);
|
|
53
|
+
return { output };
|
|
54
|
+
},
|
|
55
|
+
mermaid: async (args) => {
|
|
56
|
+
const filePath = resolveFile(args, args.cwd);
|
|
57
|
+
const { generateMermaid } = await import('../cli/commands/describe.js');
|
|
58
|
+
const parseResult = await parseWorkflow(filePath);
|
|
59
|
+
if (parseResult.errors.length > 0) {
|
|
60
|
+
throw new Error(`Parse errors:\n${parseResult.errors.join('\n')}`);
|
|
61
|
+
}
|
|
62
|
+
return { output: generateMermaid(parseResult.ast) };
|
|
63
|
+
},
|
|
64
|
+
diff: async (args) => {
|
|
65
|
+
const cwd = args.cwd;
|
|
66
|
+
const fileA = cwd ? path.resolve(cwd, String(args.fileA ?? args.file)) : path.resolve(String(args.fileA ?? args.file));
|
|
67
|
+
const fileB = cwd ? path.resolve(cwd, String(args.fileB)) : path.resolve(String(args.fileB));
|
|
68
|
+
const parseA = await parseWorkflow(fileA);
|
|
69
|
+
const parseB = await parseWorkflow(fileB);
|
|
70
|
+
if (parseA.errors.length > 0)
|
|
71
|
+
throw new Error(`Parse errors in ${fileA}:\n${parseA.errors.join('\n')}`);
|
|
72
|
+
if (parseB.errors.length > 0)
|
|
73
|
+
throw new Error(`Parse errors in ${fileB}:\n${parseB.errors.join('\n')}`);
|
|
74
|
+
const diff = WorkflowDiffer.compare(parseA.ast, parseB.ast);
|
|
75
|
+
const format = args.format ?? 'text';
|
|
76
|
+
return { output: formatDiff(diff, format === 'json' ? 'json' : 'text') };
|
|
77
|
+
},
|
|
78
|
+
context: async (args) => {
|
|
79
|
+
const { buildContext } = await import('../context/index.js');
|
|
80
|
+
const preset = args.preset;
|
|
81
|
+
const result = buildContext(preset ? { preset } : undefined);
|
|
82
|
+
return { output: result.content };
|
|
83
|
+
},
|
|
84
|
+
modify: async (args) => {
|
|
85
|
+
const filePath = resolveFile(args, args.cwd);
|
|
86
|
+
const operation = String(args.operation);
|
|
87
|
+
const params = args.params ?? {};
|
|
88
|
+
const validation = validateModifyParams(operation, params);
|
|
89
|
+
if (!validation.success) {
|
|
90
|
+
throw new Error(validation.error);
|
|
91
|
+
}
|
|
92
|
+
const source = fs.readFileSync(filePath, 'utf-8');
|
|
93
|
+
const parseResult = await parseWorkflow(filePath);
|
|
94
|
+
if (parseResult.errors.length > 0) {
|
|
95
|
+
throw new Error(`Parse errors:\n${parseResult.errors.join('\n')}`);
|
|
96
|
+
}
|
|
97
|
+
const { ast: modifiedAST } = applyModifyOperation(parseResult.ast, operation, params);
|
|
98
|
+
const result = generateInPlace(source, modifiedAST);
|
|
99
|
+
fs.writeFileSync(filePath, result.code, 'utf-8');
|
|
100
|
+
return { files: [filePath] };
|
|
101
|
+
},
|
|
102
|
+
'add-node': async (args) => {
|
|
103
|
+
const filePath = resolveFile(args, args.cwd);
|
|
104
|
+
const source = fs.readFileSync(filePath, 'utf-8');
|
|
105
|
+
const parseResult = await parseWorkflow(filePath);
|
|
106
|
+
if (parseResult.errors.length > 0) {
|
|
107
|
+
throw new Error(`Parse errors:\n${parseResult.errors.join('\n')}`);
|
|
108
|
+
}
|
|
109
|
+
const { ast } = applyModifyOperation(parseResult.ast, 'addNode', {
|
|
110
|
+
nodeId: String(args.nodeId), nodeType: String(args.nodeType),
|
|
111
|
+
});
|
|
112
|
+
const result = generateInPlace(source, ast);
|
|
113
|
+
fs.writeFileSync(filePath, result.code, 'utf-8');
|
|
114
|
+
return { files: [filePath] };
|
|
115
|
+
},
|
|
116
|
+
'remove-node': async (args) => {
|
|
117
|
+
const filePath = resolveFile(args, args.cwd);
|
|
118
|
+
const source = fs.readFileSync(filePath, 'utf-8');
|
|
119
|
+
const parseResult = await parseWorkflow(filePath);
|
|
120
|
+
if (parseResult.errors.length > 0) {
|
|
121
|
+
throw new Error(`Parse errors:\n${parseResult.errors.join('\n')}`);
|
|
122
|
+
}
|
|
123
|
+
const { ast } = applyModifyOperation(parseResult.ast, 'removeNode', { nodeId: String(args.nodeId) });
|
|
124
|
+
const result = generateInPlace(source, ast);
|
|
125
|
+
fs.writeFileSync(filePath, result.code, 'utf-8');
|
|
126
|
+
return { files: [filePath] };
|
|
127
|
+
},
|
|
128
|
+
'add-connection': async (args) => {
|
|
129
|
+
const filePath = resolveFile(args, args.cwd);
|
|
130
|
+
const source = fs.readFileSync(filePath, 'utf-8');
|
|
131
|
+
const parseResult = await parseWorkflow(filePath);
|
|
132
|
+
if (parseResult.errors.length > 0) {
|
|
133
|
+
throw new Error(`Parse errors:\n${parseResult.errors.join('\n')}`);
|
|
134
|
+
}
|
|
135
|
+
const { ast } = applyModifyOperation(parseResult.ast, 'addConnection', {
|
|
136
|
+
from: String(args.from), to: String(args.to),
|
|
137
|
+
});
|
|
138
|
+
const result = generateInPlace(source, ast);
|
|
139
|
+
fs.writeFileSync(filePath, result.code, 'utf-8');
|
|
140
|
+
return { files: [filePath] };
|
|
141
|
+
},
|
|
142
|
+
'remove-connection': async (args) => {
|
|
143
|
+
const filePath = resolveFile(args, args.cwd);
|
|
144
|
+
const source = fs.readFileSync(filePath, 'utf-8');
|
|
145
|
+
const parseResult = await parseWorkflow(filePath);
|
|
146
|
+
if (parseResult.errors.length > 0) {
|
|
147
|
+
throw new Error(`Parse errors:\n${parseResult.errors.join('\n')}`);
|
|
148
|
+
}
|
|
149
|
+
const { ast } = applyModifyOperation(parseResult.ast, 'removeConnection', {
|
|
150
|
+
from: String(args.from), to: String(args.to),
|
|
151
|
+
});
|
|
152
|
+
const result = generateInPlace(source, ast);
|
|
153
|
+
fs.writeFileSync(filePath, result.code, 'utf-8');
|
|
154
|
+
return { files: [filePath] };
|
|
155
|
+
},
|
|
156
|
+
scaffold: async (args) => {
|
|
157
|
+
const filePath = resolveFile(args, args.cwd);
|
|
158
|
+
const workflowName = path.basename(filePath, '.ts');
|
|
159
|
+
const code = generateWorkflowFromTemplate(String(args.template), { workflowName });
|
|
160
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
161
|
+
fs.writeFileSync(filePath, code, 'utf-8');
|
|
162
|
+
return { files: [filePath] };
|
|
163
|
+
},
|
|
164
|
+
query: async (args) => {
|
|
165
|
+
const filePath = resolveFile(args, args.cwd);
|
|
166
|
+
const parseResult = await parseWorkflow(filePath);
|
|
167
|
+
if (parseResult.errors.length > 0) {
|
|
168
|
+
throw new Error(`Parse errors:\n${parseResult.errors.join('\n')}`);
|
|
169
|
+
}
|
|
170
|
+
const ast = parseResult.ast;
|
|
171
|
+
const queryType = String(args.query);
|
|
172
|
+
let data;
|
|
173
|
+
switch (queryType) {
|
|
174
|
+
case 'nodes':
|
|
175
|
+
data = { nodes: getNodes(ast).map((n) => ({ id: n.id, type: n.nodeType })) };
|
|
176
|
+
break;
|
|
177
|
+
case 'connections':
|
|
178
|
+
data = { connections: getConnections(ast).map((c) => ({ from: `${c.from.node}.${c.from.port}`, to: `${c.to.node}.${c.to.port}` })) };
|
|
179
|
+
break;
|
|
180
|
+
case 'isolated':
|
|
181
|
+
data = { isolated: findIsolatedNodes(ast) };
|
|
182
|
+
break;
|
|
183
|
+
case 'dead-ends':
|
|
184
|
+
data = { deadEnds: findDeadEnds(ast) };
|
|
185
|
+
break;
|
|
186
|
+
case 'topology':
|
|
187
|
+
data = { order: getTopologicalOrder(ast) };
|
|
188
|
+
break;
|
|
189
|
+
case 'stats':
|
|
190
|
+
data = { nodeCount: countNodes(ast), connectionCount: countConnections(ast), isolatedNodes: findIsolatedNodes(ast), deadEnds: findDeadEnds(ast) };
|
|
191
|
+
break;
|
|
192
|
+
default:
|
|
193
|
+
throw new Error(`Unknown query type: ${queryType}. Valid types: nodes, connections, isolated, dead-ends, topology, stats`);
|
|
194
|
+
}
|
|
195
|
+
return { data };
|
|
196
|
+
},
|
|
197
|
+
run: async (args) => {
|
|
198
|
+
const filePath = resolveFile(args, args.cwd);
|
|
199
|
+
const { executeWorkflowFromFile } = await import('../mcp/workflow-executor.js');
|
|
200
|
+
const params = args.params ?? {};
|
|
201
|
+
const result = await executeWorkflowFromFile(filePath, params, {
|
|
202
|
+
workflowName: args.workflow,
|
|
203
|
+
});
|
|
204
|
+
return { data: result };
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
export async function runCommand(name, args) {
|
|
208
|
+
const handler = handlers[name];
|
|
209
|
+
if (!handler) {
|
|
210
|
+
throw new Error(`Unknown command: ${name}. Available: ${Object.keys(handlers).join(', ')}`);
|
|
211
|
+
}
|
|
212
|
+
return handler(args);
|
|
213
|
+
}
|
|
214
|
+
export function getAvailableCommands() {
|
|
215
|
+
return Object.keys(handlers);
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=command-runner.js.map
|
package/dist/api/index.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export * from './builder.js';
|
|
|
45
45
|
export * from './workflow-file-operations.js';
|
|
46
46
|
export * from './templates.js';
|
|
47
47
|
export * from './patterns.js';
|
|
48
|
+
export { type CommandResult, runCommand, getAvailableCommands } from './command-runner.js';
|
|
48
49
|
export { AnnotationParser } from '../parser.js';
|
|
49
50
|
export { compileTargetRegistry, type CompileTarget } from '../generator/compile-target-registry.js';
|
|
50
51
|
export { devModeRegistry, type DevModeProvider, type DevModeOptions } from '../generator/dev-mode-registry.js';
|
package/dist/api/index.js
CHANGED
|
@@ -44,6 +44,7 @@ export * from './builder.js';
|
|
|
44
44
|
export * from './workflow-file-operations.js';
|
|
45
45
|
export * from './templates.js';
|
|
46
46
|
export * from './patterns.js';
|
|
47
|
+
export { runCommand, getAvailableCommands } from './command-runner.js';
|
|
47
48
|
// Re-exports needed by export target packs
|
|
48
49
|
export { AnnotationParser } from '../parser.js';
|
|
49
50
|
export { compileTargetRegistry } from '../generator/compile-target-registry.js';
|