@synergenius/flow-weaver 0.20.7 → 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.
Files changed (54) hide show
  1. package/dist/api/command-runner.d.ts +13 -0
  2. package/dist/api/command-runner.js +217 -0
  3. package/dist/api/index.d.ts +1 -0
  4. package/dist/api/index.js +1 -0
  5. package/dist/cli/flow-weaver.mjs +24064 -38374
  6. package/dist/cli/index.js +0 -60
  7. package/dist/doc-metadata/extractors/cli-commands.js +37 -56
  8. package/dist/doc-metadata/extractors/mcp-tools.d.ts +1 -1
  9. package/dist/doc-metadata/extractors/mcp-tools.js +1 -213
  10. package/dist/doc-metadata/types.d.ts +2 -0
  11. package/dist/generated-version.d.ts +1 -1
  12. package/dist/generated-version.js +1 -1
  13. package/dist/mcp/index.d.ts +1 -5
  14. package/dist/mcp/index.js +0 -4
  15. package/dist/mcp/server.js +3 -55
  16. package/dist/mcp/types.d.ts +0 -50
  17. package/dist/mcp/types.js +1 -7
  18. package/dist/mcp/workflow-executor.js +23 -1
  19. package/dist/parser.js +5 -1
  20. package/package.json +1 -2
  21. package/dist/cli/commands/listen.d.ts +0 -16
  22. package/dist/cli/commands/listen.js +0 -39
  23. package/dist/cli/commands/tunnel.d.ts +0 -19
  24. package/dist/cli/commands/tunnel.js +0 -119
  25. package/dist/cli/commands/ui.d.ts +0 -16
  26. package/dist/cli/commands/ui.js +0 -130
  27. package/dist/cli/tunnel/dispatch.d.ts +0 -18
  28. package/dist/cli/tunnel/dispatch.js +0 -36
  29. package/dist/cli/tunnel/file-lock.d.ts +0 -9
  30. package/dist/cli/tunnel/file-lock.js +0 -36
  31. package/dist/cli/tunnel/handlers/ast-ops.d.ts +0 -10
  32. package/dist/cli/tunnel/handlers/ast-ops.js +0 -252
  33. package/dist/cli/tunnel/handlers/execution.d.ts +0 -7
  34. package/dist/cli/tunnel/handlers/execution.js +0 -89
  35. package/dist/cli/tunnel/handlers/file-ops.d.ts +0 -7
  36. package/dist/cli/tunnel/handlers/file-ops.js +0 -204
  37. package/dist/cli/tunnel/handlers/mutations.d.ts +0 -7
  38. package/dist/cli/tunnel/handlers/mutations.js +0 -285
  39. package/dist/cli/tunnel/handlers/stubs.d.ts +0 -7
  40. package/dist/cli/tunnel/handlers/stubs.js +0 -143
  41. package/dist/cli/tunnel/handlers/templates.d.ts +0 -7
  42. package/dist/cli/tunnel/handlers/templates.js +0 -123
  43. package/dist/cli/tunnel/path-resolver.d.ts +0 -17
  44. package/dist/cli/tunnel/path-resolver.js +0 -54
  45. package/dist/defaults.d.ts +0 -3
  46. package/dist/defaults.js +0 -3
  47. package/dist/mcp/editor-connection.d.ts +0 -52
  48. package/dist/mcp/editor-connection.js +0 -142
  49. package/dist/mcp/event-buffer.d.ts +0 -62
  50. package/dist/mcp/event-buffer.js +0 -150
  51. package/dist/mcp/resources.d.ts +0 -14
  52. package/dist/mcp/resources.js +0 -55
  53. package/dist/mcp/tools-editor.d.ts +0 -5
  54. package/dist/mcp/tools-editor.js +0 -283
@@ -1,285 +0,0 @@
1
- /**
2
- * Workflow mutation handlers for the tunnel CLI.
3
- * Ported from flow-weaver-platform/src/services/ast-helpers.ts mutation wrappers.
4
- */
5
- import * as fs from 'node:fs/promises';
6
- import * as path from 'node:path';
7
- import { parser, resolveNpmNodeTypes } from '../../../parser.js';
8
- import { generateInPlace } from '../../../api/generate-in-place.js';
9
- import { addNode, removeNode, updateNode, renameNode, setNodePosition, setNodeMinimized, setNodeSize, } from '../../../api/manipulation/nodes.js';
10
- import { addConnection, removeConnection } from '../../../api/manipulation/connections.js';
11
- import { addNodeType, removeNodeType, renameNodeType, updateNodeType, } from '../../../api/manipulation/node-types.js';
12
- import { setStartExitPorts, setInstancePortConfigs } from '../../../api/manipulation/ports.js';
13
- import { resolvePath } from '../path-resolver.js';
14
- import { withFileLock } from '../file-lock.js';
15
- import { prepareMutationResult, getWorkflowName } from './ast-ops.js';
16
- // ---------------------------------------------------------------------------
17
- // Core mutation engine — ported from ast-helpers.ts:95-159
18
- // ---------------------------------------------------------------------------
19
- async function mutateWorkflowFile({ filePath, functionName, mutator, }) {
20
- return withFileLock(filePath, async () => {
21
- const sourceCode = await fs.readFile(filePath, 'utf-8');
22
- const parsed = parser.parse(filePath);
23
- const workflows = parsed.workflows || [];
24
- if (workflows.length === 0) {
25
- throw new Error(`No workflows found in ${filePath}`);
26
- }
27
- const targetIndex = functionName
28
- ? workflows.findIndex((w) => w.functionName === functionName)
29
- : 0;
30
- if (targetIndex < 0) {
31
- throw new Error(`Workflow "${functionName}" not found in ${filePath}`);
32
- }
33
- const original = workflows[targetIndex];
34
- const updated = mutator(original);
35
- // Preserve importSource for node types through mutation
36
- const importSourceMap = new Map();
37
- for (const nt of original.nodeTypes || []) {
38
- if (nt.importSource) {
39
- importSourceMap.set(nt.name, nt.importSource);
40
- }
41
- }
42
- const updatedNodeTypes = (updated.nodeTypes || []).map((nt) => {
43
- if (!nt.importSource && importSourceMap.has(nt.name)) {
44
- return { ...nt, importSource: importSourceMap.get(nt.name) };
45
- }
46
- return nt;
47
- });
48
- // Re-append node types that existed in original but are missing after mutation
49
- const updatedTypeNames = new Set(updatedNodeTypes.map((nt) => nt.name));
50
- const missingTypes = [];
51
- for (const nt of original.nodeTypes || []) {
52
- if (!updatedTypeNames.has(nt.name)) {
53
- missingTypes.push(nt);
54
- }
55
- }
56
- const workflowForGeneration = {
57
- ...updated,
58
- nodeTypes: [...updatedNodeTypes, ...missingTypes],
59
- };
60
- const result = generateInPlace(sourceCode, workflowForGeneration);
61
- await fs.writeFile(filePath, result.code, 'utf-8');
62
- return resolveNpmNodeTypes(updated, path.dirname(filePath));
63
- });
64
- }
65
- // ---------------------------------------------------------------------------
66
- // Handler factory — reduces boilerplate for simple mutations
67
- // ---------------------------------------------------------------------------
68
- function makeMutationHandler(extractMutator) {
69
- return async (params, ctx) => {
70
- const filePath = params.filePath;
71
- if (!filePath)
72
- throw new Error('filePath is required');
73
- const functionName = getWorkflowName(params);
74
- const resolved = resolvePath(ctx.workspaceRoot, filePath);
75
- const result = await mutateWorkflowFile({
76
- filePath: resolved,
77
- functionName,
78
- mutator: extractMutator(params),
79
- });
80
- return prepareMutationResult(result, ctx.workspaceRoot);
81
- };
82
- }
83
- // ---------------------------------------------------------------------------
84
- // Exported handlers
85
- // ---------------------------------------------------------------------------
86
- export const mutationHandlers = {
87
- addNode: makeMutationHandler((params) => {
88
- let node = params.node;
89
- if (!node) {
90
- const nodeType = params.nodeType;
91
- const nodeName = params.nodeName;
92
- const position = params.position;
93
- node = { type: 'NodeInstance', id: nodeName, nodeType, ...(position && { position }) };
94
- }
95
- return (wf) => addNode(wf, node);
96
- }),
97
- removeNode: makeMutationHandler((params) => {
98
- const nodeId = (params.nodeName || params.nodeId);
99
- if (!nodeId)
100
- throw new Error('nodeId is required');
101
- return (wf) => removeNode(wf, nodeId, { removeConnections: true });
102
- }),
103
- updateNode: makeMutationHandler((params) => {
104
- const nodeId = (params.nodeId || params.nodeName);
105
- const updates = params.updates;
106
- if (!nodeId)
107
- throw new Error('nodeId is required');
108
- return (wf) => updateNode(wf, nodeId, updates);
109
- }),
110
- renameNode: makeMutationHandler((params) => {
111
- const oldId = params.oldId;
112
- const newId = params.newId;
113
- if (!oldId || !newId)
114
- throw new Error('oldId and newId are required');
115
- return (wf) => renameNode(wf, oldId, newId);
116
- }),
117
- setNodePosition: makeMutationHandler((params) => {
118
- const nodeId = params.nodeId;
119
- const x = params.x;
120
- const y = params.y;
121
- return (wf) => setNodePosition(wf, nodeId, x, y);
122
- }),
123
- setNodePositions: makeMutationHandler((params) => {
124
- const positions = params.positions;
125
- if (!positions)
126
- throw new Error('positions are required');
127
- return (wf) => {
128
- let result = wf;
129
- for (const { nodeId, x, y } of positions) {
130
- result = setNodePosition(result, nodeId, x, y);
131
- }
132
- return result;
133
- };
134
- }),
135
- setNodeMinimized: makeMutationHandler((params) => {
136
- const nodeId = params.nodeId;
137
- const minimized = params.minimized;
138
- return (wf) => setNodeMinimized(wf, nodeId, minimized);
139
- }),
140
- setNodeSize: makeMutationHandler((params) => {
141
- const nodeId = params.nodeId;
142
- const width = params.width;
143
- const height = params.height;
144
- return (wf) => setNodeSize(wf, nodeId, width, height);
145
- }),
146
- setNodeLabel: makeMutationHandler((params) => {
147
- const nodeId = params.nodeId;
148
- const label = params.label;
149
- return (wf) => updateNode(wf, nodeId, { label });
150
- }),
151
- addNodes: makeMutationHandler((params) => {
152
- const nodes = params.nodes;
153
- if (!nodes)
154
- throw new Error('nodes are required');
155
- return (wf) => {
156
- let result = wf;
157
- for (const node of nodes) {
158
- result = addNode(result, node);
159
- }
160
- return result;
161
- };
162
- }),
163
- removeNodes: makeMutationHandler((params) => {
164
- const nodeIds = params.nodeIds;
165
- if (!nodeIds)
166
- throw new Error('nodeIds are required');
167
- return (wf) => {
168
- let result = wf;
169
- for (const nodeId of nodeIds) {
170
- result = removeNode(result, nodeId, { removeConnections: true });
171
- }
172
- return result;
173
- };
174
- }),
175
- addConnection: makeMutationHandler((params) => {
176
- const from = params.from || { node: params.fromNode, port: params.fromPort };
177
- const to = params.to || { node: params.toNode, port: params.toPort };
178
- return (wf) => addConnection(wf, from, to);
179
- }),
180
- removeConnection: makeMutationHandler((params) => {
181
- const from = params.from || { node: params.fromNode, port: params.fromPort };
182
- const to = params.to || { node: params.toNode, port: params.toPort };
183
- return (wf) => removeConnection(wf, from, to);
184
- }),
185
- setConnections: makeMutationHandler((params) => {
186
- const connections = params.connections;
187
- return (wf) => ({ ...wf, connections });
188
- }),
189
- addConnections: makeMutationHandler((params) => {
190
- const connections = params.connections;
191
- return (wf) => ({ ...wf, connections: [...wf.connections, ...connections] });
192
- }),
193
- updateNodePortConfig: makeMutationHandler((params) => {
194
- const nodeId = params.nodeId;
195
- const portName = params.portName;
196
- const portConfig = params.portConfig;
197
- return (wf) => {
198
- const node = wf.instances?.find((n) => n.id === nodeId);
199
- if (!node)
200
- throw new Error(`Node "${nodeId}" not found`);
201
- const existing = node.config?.portConfigs || [];
202
- const idx = existing.findIndex((pc) => pc.portName === portName);
203
- const updated = [...existing];
204
- if (idx >= 0) {
205
- updated[idx] = { ...updated[idx], ...portConfig };
206
- }
207
- else {
208
- updated.push({ portName, ...portConfig });
209
- }
210
- return updateNode(wf, nodeId, { config: { ...node.config, portConfigs: updated } });
211
- };
212
- }),
213
- resetNodePortConfig: makeMutationHandler((params) => {
214
- const nodeId = params.nodeId;
215
- const portName = params.portName;
216
- return (wf) => {
217
- const node = wf.instances?.find((n) => n.id === nodeId);
218
- if (!node)
219
- throw new Error(`Node "${nodeId}" not found`);
220
- const existing = node.config?.portConfigs || [];
221
- const filtered = existing.filter((pc) => pc.portName !== portName);
222
- return updateNode(wf, nodeId, { config: { ...node.config, portConfigs: filtered } });
223
- };
224
- }),
225
- updateInstancePortConfigs: makeMutationHandler((params) => {
226
- const instanceId = params.instanceId;
227
- const portConfigs = params.portConfigs;
228
- return (wf) => setInstancePortConfigs(wf, instanceId, portConfigs);
229
- }),
230
- updateWorkflowPorts: makeMutationHandler((params) => {
231
- const nodeType = params.nodeType;
232
- const ports = params.ports;
233
- return (wf) => setStartExitPorts(wf, nodeType, ports);
234
- }),
235
- addNodeType: makeMutationHandler((params) => {
236
- const nodeType = params.nodeType;
237
- return (wf) => addNodeType(wf, nodeType);
238
- }),
239
- removeNodeType: makeMutationHandler((params) => {
240
- const typeName = params.typeName;
241
- if (!typeName)
242
- throw new Error('typeName is required');
243
- return (wf) => removeNodeType(wf, typeName);
244
- }),
245
- renameNodeType: makeMutationHandler((params) => {
246
- const oldTypeName = params.oldTypeName;
247
- const newTypeName = params.newTypeName;
248
- return (wf) => renameNodeType(wf, oldTypeName, newTypeName);
249
- }),
250
- updateNodeType: makeMutationHandler((params) => {
251
- const typeName = params.typeName;
252
- const updates = params.updates;
253
- return (wf) => updateNodeType(wf, typeName, updates);
254
- }),
255
- setNodeTypes: makeMutationHandler((params) => {
256
- const nodeTypes = params.nodeTypes;
257
- return (wf) => ({ ...wf, nodeTypes });
258
- }),
259
- saveWorkflowState: makeMutationHandler((params) => {
260
- const workflow = params.workflow;
261
- return () => workflow;
262
- }),
263
- setNodeParent: makeMutationHandler((params) => {
264
- const nodeId = params.nodeId;
265
- const parentId = params.parentId;
266
- return (wf) => updateNode(wf, nodeId, { parent: parentId });
267
- }),
268
- setNodesParent: makeMutationHandler((params) => {
269
- const nodeIds = params.nodeIds;
270
- const parentId = params.parentId;
271
- return (wf) => {
272
- let result = wf;
273
- for (const nodeId of nodeIds) {
274
- result = updateNode(result, nodeId, { parent: parentId });
275
- }
276
- return result;
277
- };
278
- }),
279
- setCurrentWorkflow: async () => ({ success: true }),
280
- setWorkflowForceAsync: makeMutationHandler((params) => {
281
- const forceAsync = params.forceAsync;
282
- return (wf) => ({ ...wf, forceAsync });
283
- }),
284
- };
285
- //# sourceMappingURL=mutations.js.map
@@ -1,7 +0,0 @@
1
- /**
2
- * Stub handlers — methods that return sensible defaults.
3
- * Matches the no-op return values from flow-weaver-platform/src/routes/studio-rpc.ts.
4
- */
5
- import type { HandlerFn } from '../dispatch.js';
6
- export declare const stubHandlers: Record<string, HandlerFn>;
7
- //# sourceMappingURL=stubs.d.ts.map
@@ -1,143 +0,0 @@
1
- /**
2
- * Stub handlers — methods that return sensible defaults.
3
- * Matches the no-op return values from flow-weaver-platform/src/routes/studio-rpc.ts.
4
- */
5
- import * as os from 'node:os';
6
- const stub = (value) => () => Promise.resolve(value);
7
- const lazyStub = (fn) => () => Promise.resolve(fn());
8
- export const stubHandlers = {
9
- // --- Completions / Quick Info ---
10
- getCompletions: stub([]),
11
- getQuickInfo: stub(undefined),
12
- // --- Snapshots (undo/redo state is client-side) ---
13
- takeWorkflowSnapshot: stub({ success: true }),
14
- deleteWorkflowSnapshot: stub({ success: true }),
15
- deleteAllWorkflowSnapshots: stub({ success: true }),
16
- cleanupOldWorkflowSnapshots: stub({ success: true }),
17
- loadWorkflowSnapshot: stub(null),
18
- getLatestWorkflowSnapshot: stub(null),
19
- getWorkflowSnapshotAtIndex: stub(null),
20
- findCommonBaseSnapshot: stub(null),
21
- listWorkflowSnapshots: stub([]),
22
- // --- Backups ---
23
- createBackup: stub({ success: true }),
24
- listBackups: stub([]),
25
- restoreBackup: stub({ success: true }),
26
- deleteBackup: stub({ success: true }),
27
- cleanupOldBackups: stub({ success: true }),
28
- // --- Deployment profiles / project config ---
29
- listDeploymentProfiles: stub([]),
30
- readDeploymentProfile: stub(null),
31
- readProjectConfig: stub(null),
32
- writeDeploymentProfile: stub({ success: true }),
33
- deleteDeploymentProfile: stub({ success: true }),
34
- setActiveDeploymentProfile: stub({ success: true }),
35
- writeProjectConfig: stub({ success: true }),
36
- // --- Export ---
37
- exportWorkflow: stub({ success: true }),
38
- exportMultiWorkflow: stub({ success: true }),
39
- exportNodeTypes: stub({ success: true }),
40
- exportBundle: stub({ success: true }),
41
- // --- Misc ---
42
- getUserDataPath: lazyStub(() => os.tmpdir()),
43
- getTempDirectory: lazyStub(() => os.tmpdir()),
44
- openDirectoryInExplorer: stub({ success: true }),
45
- checkDeployPrerequisites: stub({ success: true }),
46
- appendToLog: stub(undefined),
47
- getMatchingFileList: stub([]),
48
- generateAnnotationSuggestion: stub(null),
49
- addWorkflowToFile: stub({ success: true }),
50
- removeWorkflowFromFile: stub({ success: true }),
51
- toggleWorkflowExportInFile: stub({ success: true }),
52
- getAvailableNodeTypesInFile: stub([]),
53
- scanProjectBundleItems: stub([]),
54
- getAvailableItemsInWorkdir: stub([]),
55
- getAvailableItemsInFiles: stub([]),
56
- getWorkflowEndpointInfo: stub(null),
57
- callTool: stub(undefined),
58
- getTypedPackages: stub([]),
59
- getPackageExports: stub([]),
60
- warmUpWorkflowCache: stub(undefined),
61
- preBundleWorkflow: stub(undefined),
62
- getLocalFunctionCode: stub(null),
63
- evaluateExpression: stub(undefined),
64
- interruptExecution: stub({ success: false }),
65
- setWatcher: stub({ success: true }),
66
- stopWatcher: stub({ success: true }),
67
- // --- Marketplace ---
68
- marketplaceSearch: stub({ results: [] }),
69
- marketplaceListInstalled: stub([]),
70
- marketplaceInstall: stub({ success: true }),
71
- // --- Patterns ---
72
- getPatterns: stub([]),
73
- applyPatternToWorkflow: stub({ success: true }),
74
- extractPatternFromWorkflow: stub({ success: true }),
75
- // --- Plugins ---
76
- initializePlugins: stub(undefined),
77
- cleanupPlugins: stub(undefined),
78
- getPlugins: stub([]),
79
- getPluginSystemStatus: stub({ status: 'ready' }),
80
- callPlugin: stub(undefined),
81
- // --- Git ---
82
- getRepository: stub({}),
83
- gitInit: stub({}),
84
- gitClone: stub({}),
85
- gitStatus: stub({
86
- files: [],
87
- modified: [],
88
- not_added: [],
89
- created: [],
90
- deleted: [],
91
- renamed: [],
92
- conflicted: [],
93
- ignored: [],
94
- current: 'main',
95
- }),
96
- gitCommit: stub({ success: true }),
97
- gitPush: stub({ success: true }),
98
- gitPull: stub({ success: true }),
99
- gitFetch: stub({ success: true }),
100
- gitStageFiles: stub({ success: true }),
101
- gitGetWorkingDiff: stub({ success: true }),
102
- gitHistory: stub({ success: true }),
103
- gitGetCommitFiles: stub({ success: true }),
104
- gitGetCommitDiff: stub({ success: true }),
105
- gitGetFileAtCommit: stub({ success: true }),
106
- gitBranchList: stub({ success: true, branches: ['main'], current: 'main' }),
107
- gitBranchCreate: stub({ success: true }),
108
- gitBranchCheckout: stub({ success: true }),
109
- gitTagCreate: stub({ success: true }),
110
- gitTagDelete: stub({ success: true }),
111
- gitStashSave: stub({ success: true }),
112
- gitStashApply: stub({ success: true }),
113
- gitRemoteAdd: stub({ success: true }),
114
- gitRemoteFetch: stub({ success: true }),
115
- gitMerge: stub({ success: true }),
116
- gitReset: stub({ success: true }),
117
- gitTagList: stub({ success: true, tags: [] }),
118
- gitStashList: stub({ success: true, stashes: [] }),
119
- gitRemoteList: stub({ success: true, remotes: [] }),
120
- gitRepoList: stub([]),
121
- // --- Terminal (stub for now — requires node-pty) ---
122
- createTerminal: stub({ success: false, error: 'Terminal not supported in tunnel mode' }),
123
- writeToTerminal: stub({ success: false }),
124
- resizeTerminal: stub({ success: false }),
125
- closeTerminal: stub({ success: false }),
126
- pauseTerminal: stub({ success: false }),
127
- resumeTerminal: stub({ success: false }),
128
- listTerminals: stub([]),
129
- // --- Debug ---
130
- debugCreateSession: stub(undefined),
131
- debugEndSession: stub(undefined),
132
- debugSetBreakpoints: stub(undefined),
133
- debugResume: stub(undefined),
134
- debugStepOver: stub(undefined),
135
- debugStepInto: stub(undefined),
136
- debugStepOut: stub(undefined),
137
- debugEvaluateExpression: stub(undefined),
138
- debugInspectVariable: stub(undefined),
139
- // --- Doctor ---
140
- runDoctor: stub({ status: 'healthy', checks: [], summary: { passed: 0, failed: 0, warnings: 0 } }),
141
- runDoctorChecks: stub({ status: 'healthy', checks: [], summary: { passed: 0, failed: 0, warnings: 0 } }),
142
- };
143
- //# sourceMappingURL=stubs.js.map
@@ -1,7 +0,0 @@
1
- /**
2
- * Template operation handlers for the tunnel CLI.
3
- * Ported from flow-weaver-platform/src/services/ast-helpers.ts template operations.
4
- */
5
- import type { HandlerFn } from '../dispatch.js';
6
- export declare const templateHandlers: Record<string, HandlerFn>;
7
- //# sourceMappingURL=templates.d.ts.map
@@ -1,123 +0,0 @@
1
- /**
2
- * Template operation handlers for the tunnel CLI.
3
- * Ported from flow-weaver-platform/src/services/ast-helpers.ts template operations.
4
- */
5
- import * as fs from 'node:fs/promises';
6
- import * as path from 'node:path';
7
- import { parser } from '../../../parser.js';
8
- import { workflowTemplates, nodeTemplates, getWorkflowTemplate, getNodeTemplate, } from '../../templates/index.js';
9
- import { resolvePath } from '../path-resolver.js';
10
- function mapTemplate(t) {
11
- return {
12
- id: t.id,
13
- name: t.name,
14
- description: t.description,
15
- category: t.category,
16
- ...(t.configSchema && { configSchema: t.configSchema }),
17
- };
18
- }
19
- export const templateHandlers = {
20
- listTemplates: async (params) => {
21
- const type = params.type || 'workflow';
22
- const templates = type === 'node' ? nodeTemplates : workflowTemplates;
23
- return { templates: templates.map(mapTemplate) };
24
- },
25
- getTemplate: async (params) => {
26
- const type = params.type || 'workflow';
27
- const id = params.id;
28
- if (!id)
29
- throw new Error('id is required');
30
- const template = type === 'node' ? getNodeTemplate(id) : getWorkflowTemplate(id);
31
- return template ? mapTemplate(template) : null;
32
- },
33
- getTemplatePreviewAST: async (params) => {
34
- const templateId = params.templateId;
35
- if (!templateId)
36
- return { ast: null };
37
- const template = getWorkflowTemplate(templateId);
38
- if (!template)
39
- return { ast: null };
40
- try {
41
- const code = template.generate({ workflowName: 'preview' });
42
- const parsed = parser.parseFromString(code);
43
- const workflows = parsed.workflows || [];
44
- return { ast: workflows[0] || null };
45
- }
46
- catch {
47
- return { ast: null };
48
- }
49
- },
50
- generateWorkflowCode: async (params) => {
51
- const templateId = params.templateId;
52
- const workflowName = params.workflowName;
53
- if (!templateId || !workflowName)
54
- throw new Error('templateId and workflowName are required');
55
- const template = getWorkflowTemplate(templateId);
56
- if (!template)
57
- throw new Error(`Template "${templateId}" not found`);
58
- const options = { workflowName };
59
- if (params.async !== undefined)
60
- options.async = params.async;
61
- if (params.config)
62
- options.config = params.config;
63
- const code = template.generate(options);
64
- return { code };
65
- },
66
- generateNodeCode: async (params) => {
67
- const templateId = params.templateId;
68
- const name = params.name;
69
- if (!templateId || !name)
70
- throw new Error('templateId and name are required');
71
- const template = getNodeTemplate(templateId);
72
- if (!template)
73
- throw new Error(`Node template "${templateId}" not found`);
74
- const code = template.generate(name, params.config);
75
- return { code };
76
- },
77
- getNodeTemplatePreview: async (params) => {
78
- const templateId = params.templateId;
79
- const name = params.name || 'preview';
80
- const template = getNodeTemplate(templateId);
81
- if (!template)
82
- return null;
83
- try {
84
- const code = template.generate(name);
85
- const parsed = parser.parseFromString(code);
86
- const workflows = parsed.workflows || [];
87
- const nodeTypes = workflows[0]?.nodeTypes || [];
88
- if (nodeTypes.length === 0)
89
- return null;
90
- const nt = nodeTypes[0];
91
- return {
92
- name: nt.name,
93
- inputs: nt.inputs || nt.ports?.filter((p) => p.direction === 'input') || [],
94
- outputs: nt.outputs || nt.ports?.filter((p) => p.direction === 'output') || [],
95
- };
96
- }
97
- catch {
98
- return null;
99
- }
100
- },
101
- createWorkflowFromTemplate: async (params, ctx) => {
102
- const templateId = params.templateId;
103
- const workflowName = params.workflowName;
104
- const fileName = params.fileName;
105
- if (!templateId || !workflowName)
106
- throw new Error('templateId and workflowName are required');
107
- const template = getWorkflowTemplate(templateId);
108
- if (!template)
109
- throw new Error(`Template "${templateId}" not found`);
110
- const genOpts = { workflowName };
111
- if (params.async !== undefined)
112
- genOpts.async = params.async;
113
- if (params.config)
114
- genOpts.config = params.config;
115
- const code = template.generate(genOpts);
116
- const targetFileName = fileName || `${workflowName}.ts`;
117
- const resolved = resolvePath(ctx.workspaceRoot, targetFileName);
118
- await fs.mkdir(path.dirname(resolved), { recursive: true });
119
- await fs.writeFile(resolved, code, 'utf-8');
120
- return { success: true, filePath: '/' + targetFileName };
121
- },
122
- };
123
- //# sourceMappingURL=templates.js.map
@@ -1,17 +0,0 @@
1
- /**
2
- * Path resolution with traversal protection for the tunnel CLI.
3
- *
4
- * Ported from flow-weaver-platform/src/services/workspace.ts:89-125.
5
- * Virtual paths from Studio (e.g. `/workflow.ts`) are resolved to absolute
6
- * filesystem paths within the workspace root.
7
- */
8
- /**
9
- * Resolve a Studio virtual path to an absolute filesystem path.
10
- * Blocks null bytes and path traversal.
11
- */
12
- export declare function resolvePath(workspaceRoot: string, studioPath: string): string;
13
- /**
14
- * Convert an absolute filesystem path to a Studio virtual path.
15
- */
16
- export declare function toVirtualPath(workspaceRoot: string, realPath: string): string;
17
- //# sourceMappingURL=path-resolver.d.ts.map
@@ -1,54 +0,0 @@
1
- /**
2
- * Path resolution with traversal protection for the tunnel CLI.
3
- *
4
- * Ported from flow-weaver-platform/src/services/workspace.ts:89-125.
5
- * Virtual paths from Studio (e.g. `/workflow.ts`) are resolved to absolute
6
- * filesystem paths within the workspace root.
7
- */
8
- import * as path from 'node:path';
9
- /**
10
- * Resolve a Studio virtual path to an absolute filesystem path.
11
- * Blocks null bytes and path traversal.
12
- */
13
- export function resolvePath(workspaceRoot, studioPath) {
14
- if (studioPath.includes('\0')) {
15
- throw new Error('Path traversal blocked');
16
- }
17
- // If the path is already absolute and within the workspace, allow it
18
- if (studioPath.startsWith(workspaceRoot + path.sep) || studioPath === workspaceRoot) {
19
- const resolved = path.resolve(studioPath);
20
- if (!resolved.startsWith(workspaceRoot + path.sep) && resolved !== workspaceRoot) {
21
- throw new Error('Path traversal blocked');
22
- }
23
- return resolved;
24
- }
25
- // Normalize backslashes to forward slashes (Windows clients may send them)
26
- let normalized = studioPath.replace(/\\/g, '/');
27
- // Strip /cloud prefix if present
28
- if (normalized.startsWith('/cloud')) {
29
- normalized = normalized.slice('/cloud'.length);
30
- }
31
- // Strip leading slashes
32
- normalized = normalized.replace(/^\/+/, '');
33
- if (!normalized) {
34
- return workspaceRoot;
35
- }
36
- const resolved = path.resolve(workspaceRoot, normalized);
37
- // Block path traversal — resolved must be within workspace
38
- if (!resolved.startsWith(workspaceRoot + path.sep) && resolved !== workspaceRoot) {
39
- throw new Error('Path traversal blocked');
40
- }
41
- return resolved;
42
- }
43
- /**
44
- * Convert an absolute filesystem path to a Studio virtual path.
45
- */
46
- export function toVirtualPath(workspaceRoot, realPath) {
47
- const rel = path.relative(workspaceRoot, realPath);
48
- if (rel.startsWith('..')) {
49
- return '/' + path.basename(realPath);
50
- }
51
- // Always use forward slashes in virtual paths (Windows path.relative uses backslashes)
52
- return '/' + rel.replace(/\\/g, '/');
53
- }
54
- //# sourceMappingURL=path-resolver.js.map
@@ -1,3 +0,0 @@
1
- export declare const DEFAULT_PORT: number;
2
- export declare const DEFAULT_SERVER_URL: string;
3
- //# sourceMappingURL=defaults.d.ts.map
package/dist/defaults.js DELETED
@@ -1,3 +0,0 @@
1
- export const DEFAULT_PORT = parseInt(process.env.FW_PORT || '6546', 10);
2
- export const DEFAULT_SERVER_URL = `http://localhost:${DEFAULT_PORT}`;
3
- //# sourceMappingURL=defaults.js.map