@synergenius/flow-weaver 0.27.5 → 0.29.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/generate-in-place.js +54 -0
- package/dist/api/generate.js +20 -2
- package/dist/api/query.d.ts +3 -1
- package/dist/api/query.js +25 -1
- package/dist/ast/types.d.ts +7 -1
- package/dist/built-in-nodes/generated-registry.d.ts +9 -0
- package/dist/built-in-nodes/generated-registry.js +299 -0
- package/dist/cli/commands/init-personas.js +8 -8
- package/dist/cli/commands/init.js +18 -12
- package/dist/cli/commands/run.js +6 -0
- package/dist/cli/flow-weaver.mjs +533 -74
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +1 -1
- package/dist/generator/scope-function-generator.js +69 -43
- package/dist/parser.js +56 -12
- package/package.json +4 -2
package/dist/cli/flow-weaver.mjs
CHANGED
|
@@ -5987,7 +5987,7 @@ var VERSION;
|
|
|
5987
5987
|
var init_generated_version = __esm({
|
|
5988
5988
|
"src/generated-version.ts"() {
|
|
5989
5989
|
"use strict";
|
|
5990
|
-
VERSION = "0.
|
|
5990
|
+
VERSION = "0.29.0";
|
|
5991
5991
|
}
|
|
5992
5992
|
});
|
|
5993
5993
|
|
|
@@ -6645,18 +6645,28 @@ function generateScopeFunctionClosure(scopeName, parentNodeId, parentNodeType, w
|
|
|
6645
6645
|
}
|
|
6646
6646
|
const safeChildId = toValidIdentifier(child.id);
|
|
6647
6647
|
const awaitPrefix = isAsync2 ? "await " : "";
|
|
6648
|
+
const emitDebugHooks = !production;
|
|
6649
|
+
let childIndent = " ";
|
|
6648
6650
|
lines.push(``);
|
|
6649
6651
|
lines.push(` // Execute: ${child.id} (${child.nodeType})`);
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
lines.push(
|
|
6657
|
-
|
|
6658
|
-
lines.push(
|
|
6659
|
-
lines.push(
|
|
6652
|
+
if (emitDebugHooks) {
|
|
6653
|
+
const awaitHook = isAsync2 ? "await " : "";
|
|
6654
|
+
lines.push(` let ${safeChildId}Idx: number = -1;`);
|
|
6655
|
+
lines.push(` if (${awaitHook}__ctrl__.beforeNode('${child.id}', scopedCtx)) {`);
|
|
6656
|
+
childIndent = " ";
|
|
6657
|
+
}
|
|
6658
|
+
lines.push(`${childIndent}scopedCtx.checkAborted('${child.id}');`);
|
|
6659
|
+
const idxDecl = emitDebugHooks ? "" : "const ";
|
|
6660
|
+
lines.push(`${childIndent}${idxDecl}${safeChildId}Idx = scopedCtx.addExecution('${child.id}');`);
|
|
6661
|
+
lines.push(`${childIndent}if (typeof globalThis !== 'undefined') (globalThis as unknown as { __fw_current_node_id__?: string }).__fw_current_node_id__ = '${child.id}';`);
|
|
6662
|
+
lines.push(`${childIndent}${awaitPrefix}scopedCtx.sendStatusChangedEvent({`);
|
|
6663
|
+
lines.push(`${childIndent} nodeTypeName: '${child.nodeType}',`);
|
|
6664
|
+
lines.push(`${childIndent} id: '${child.id}',`);
|
|
6665
|
+
lines.push(`${childIndent} executionIndex: ${safeChildId}Idx,`);
|
|
6666
|
+
lines.push(`${childIndent} status: 'RUNNING',`);
|
|
6667
|
+
lines.push(`${childIndent}});`);
|
|
6668
|
+
lines.push(`${childIndent}try {`);
|
|
6669
|
+
const tryIndent = `${childIndent} `;
|
|
6660
6670
|
const argLines = [];
|
|
6661
6671
|
const getCall = isAsync2 ? "await scopedCtx.getVariable" : "scopedCtx.getVariable";
|
|
6662
6672
|
const childSetCall = isAsync2 ? `await scopedCtx.setVariable` : `scopedCtx.setVariable`;
|
|
@@ -6673,10 +6683,10 @@ function generateScopeFunctionClosure(scopeName, parentNodeId, parentNodeType, w
|
|
|
6673
6683
|
const targetPortDef = childNodeType.inputs[targetPort];
|
|
6674
6684
|
const portType = targetPortDef ? mapToTypeScript(targetPortDef.dataType, targetPortDef.tsType) : "unknown";
|
|
6675
6685
|
argLines.push(
|
|
6676
|
-
|
|
6686
|
+
`${tryIndent}const ${varName} = ${getCall}({ id: '${parentNodeId}', portName: '${conn.from.port}', executionIndex: ${scopeParamIdxVar} }) as ${portType};`
|
|
6677
6687
|
);
|
|
6678
6688
|
argLines.push(
|
|
6679
|
-
|
|
6689
|
+
`${tryIndent}${childSetCall}({ id: '${child.id}', portName: '${targetPort}', executionIndex: ${safeChildId}Idx, nodeTypeName: '${child.nodeType}' }, ${varName});`
|
|
6680
6690
|
);
|
|
6681
6691
|
preHandledPorts.add(targetPort);
|
|
6682
6692
|
}
|
|
@@ -6686,7 +6696,7 @@ function generateScopeFunctionClosure(scopeName, parentNodeId, parentNodeType, w
|
|
|
6686
6696
|
workflow: scopeWorkflow,
|
|
6687
6697
|
id: child.id,
|
|
6688
6698
|
lines: argLines,
|
|
6689
|
-
indent:
|
|
6699
|
+
indent: tryIndent,
|
|
6690
6700
|
getCall,
|
|
6691
6701
|
isAsync: isAsync2,
|
|
6692
6702
|
instanceParent: child.parent ? `${child.parent.id}.${child.parent.scope}` : void 0,
|
|
@@ -6699,11 +6709,11 @@ function generateScopeFunctionClosure(scopeName, parentNodeId, parentNodeType, w
|
|
|
6699
6709
|
argLines.forEach((line) => lines.push(line));
|
|
6700
6710
|
if (childNodeType.expression) {
|
|
6701
6711
|
lines.push(
|
|
6702
|
-
|
|
6712
|
+
`${tryIndent}const ${safeChildId}Result = ${awaitPrefix}${child.nodeType}(${args.join(", ")});`
|
|
6703
6713
|
);
|
|
6704
6714
|
} else {
|
|
6705
6715
|
lines.push(
|
|
6706
|
-
|
|
6716
|
+
`${tryIndent}const ${safeChildId}Result = ${awaitPrefix}${child.nodeType}(${args.join(", ")});`
|
|
6707
6717
|
);
|
|
6708
6718
|
}
|
|
6709
6719
|
if (childNodeType.expression) {
|
|
@@ -6711,49 +6721,56 @@ function generateScopeFunctionClosure(scopeName, parentNodeId, parentNodeType, w
|
|
|
6711
6721
|
const portDef = childNodeType.outputs[outPort];
|
|
6712
6722
|
if (portDef.failure || isFailurePort(outPort)) {
|
|
6713
6723
|
lines.push(
|
|
6714
|
-
|
|
6724
|
+
`${tryIndent}${childSetCall}({ id: '${child.id}', portName: '${outPort}', executionIndex: ${safeChildId}Idx, nodeTypeName: '${child.nodeType}' }, false);`
|
|
6715
6725
|
);
|
|
6716
6726
|
} else if (portDef.isControlFlow || isSuccessPort(outPort)) {
|
|
6717
6727
|
lines.push(
|
|
6718
|
-
|
|
6728
|
+
`${tryIndent}${childSetCall}({ id: '${child.id}', portName: '${outPort}', executionIndex: ${safeChildId}Idx, nodeTypeName: '${child.nodeType}' }, true);`
|
|
6719
6729
|
);
|
|
6720
6730
|
} else {
|
|
6721
6731
|
lines.push(
|
|
6722
|
-
|
|
6732
|
+
`${tryIndent}${childSetCall}({ id: '${child.id}', portName: '${outPort}', executionIndex: ${safeChildId}Idx, nodeTypeName: '${child.nodeType}' }, ${safeChildId}Result.${outPort});`
|
|
6723
6733
|
);
|
|
6724
6734
|
}
|
|
6725
6735
|
});
|
|
6726
6736
|
} else {
|
|
6727
6737
|
Object.keys(childNodeType.outputs || {}).forEach((outPort) => {
|
|
6728
6738
|
lines.push(
|
|
6729
|
-
|
|
6739
|
+
`${tryIndent}${childSetCall}({ id: '${child.id}', portName: '${outPort}', executionIndex: ${safeChildId}Idx, nodeTypeName: '${child.nodeType}' }, ${safeChildId}Result.${outPort});`
|
|
6730
6740
|
);
|
|
6731
6741
|
});
|
|
6732
6742
|
}
|
|
6733
|
-
lines.push(
|
|
6734
|
-
lines.push(
|
|
6735
|
-
lines.push(
|
|
6736
|
-
lines.push(
|
|
6737
|
-
lines.push(
|
|
6738
|
-
lines.push(
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
lines.push(
|
|
6744
|
-
lines.push(
|
|
6745
|
-
lines.push(`
|
|
6746
|
-
lines.push(
|
|
6747
|
-
lines.push(
|
|
6748
|
-
lines.push(
|
|
6749
|
-
lines.push(
|
|
6750
|
-
lines.push(
|
|
6751
|
-
lines.push(
|
|
6752
|
-
lines.push(
|
|
6753
|
-
lines.push(
|
|
6754
|
-
lines.push(
|
|
6755
|
-
lines.push(
|
|
6756
|
-
lines.push(
|
|
6743
|
+
lines.push(`${tryIndent}${awaitPrefix}scopedCtx.sendStatusChangedEvent({`);
|
|
6744
|
+
lines.push(`${tryIndent} nodeTypeName: '${child.nodeType}',`);
|
|
6745
|
+
lines.push(`${tryIndent} id: '${child.id}',`);
|
|
6746
|
+
lines.push(`${tryIndent} executionIndex: ${safeChildId}Idx,`);
|
|
6747
|
+
lines.push(`${tryIndent} status: 'SUCCEEDED',`);
|
|
6748
|
+
lines.push(`${tryIndent}});`);
|
|
6749
|
+
if (emitDebugHooks) {
|
|
6750
|
+
const awaitHook = isAsync2 ? "await " : "";
|
|
6751
|
+
lines.push(`${tryIndent}${awaitHook}__ctrl__.afterNode('${child.id}', scopedCtx);`);
|
|
6752
|
+
}
|
|
6753
|
+
lines.push(`${childIndent}} catch (error: unknown) {`);
|
|
6754
|
+
lines.push(`${tryIndent}const isCancellation = CancellationError.isCancellationError(error);`);
|
|
6755
|
+
lines.push(`${tryIndent}${awaitPrefix}scopedCtx.sendStatusChangedEvent({`);
|
|
6756
|
+
lines.push(`${tryIndent} nodeTypeName: '${child.nodeType}',`);
|
|
6757
|
+
lines.push(`${tryIndent} id: '${child.id}',`);
|
|
6758
|
+
lines.push(`${tryIndent} executionIndex: ${safeChildId}Idx,`);
|
|
6759
|
+
lines.push(`${tryIndent} status: isCancellation ? 'CANCELLED' : 'FAILED',`);
|
|
6760
|
+
lines.push(`${tryIndent}});`);
|
|
6761
|
+
lines.push(`${tryIndent}if (!isCancellation) {`);
|
|
6762
|
+
lines.push(`${tryIndent} scopedCtx.sendLogErrorEvent({`);
|
|
6763
|
+
lines.push(`${tryIndent} nodeTypeName: '${child.nodeType}',`);
|
|
6764
|
+
lines.push(`${tryIndent} id: '${child.id}',`);
|
|
6765
|
+
lines.push(`${tryIndent} executionIndex: ${safeChildId}Idx,`);
|
|
6766
|
+
lines.push(`${tryIndent} error: error instanceof Error ? error.message : String(error),`);
|
|
6767
|
+
lines.push(`${tryIndent} });`);
|
|
6768
|
+
lines.push(`${tryIndent}}`);
|
|
6769
|
+
lines.push(`${tryIndent}throw error;`);
|
|
6770
|
+
lines.push(`${childIndent}}`);
|
|
6771
|
+
if (emitDebugHooks) {
|
|
6772
|
+
lines.push(` }`);
|
|
6773
|
+
}
|
|
6757
6774
|
});
|
|
6758
6775
|
lines.push(``);
|
|
6759
6776
|
}
|
|
@@ -14022,8 +14039,9 @@ function generateCode(ast, options) {
|
|
|
14022
14039
|
}
|
|
14023
14040
|
}
|
|
14024
14041
|
const npmPackageNodes = ast.nodeTypes.filter((n7) => n7.importSource);
|
|
14042
|
+
const referencedNodeTypes = new Set(ast.instances.map((i) => i.nodeType));
|
|
14025
14043
|
const localNodes = ast.nodeTypes.filter(
|
|
14026
|
-
(n7) => !n7.importSource && n7.sourceLocation?.file === ast.sourceFile
|
|
14044
|
+
(n7) => !n7.importSource && (n7.sourceLocation?.file === ast.sourceFile || !n7.sourceLocation && n7.functionText && n7.helperText != null && referencedNodeTypes.has(n7.name))
|
|
14027
14045
|
);
|
|
14028
14046
|
const importedNodes = ast.nodeTypes.filter(
|
|
14029
14047
|
(n7) => !n7.importSource && n7.sourceLocation?.file !== ast.sourceFile
|
|
@@ -14134,9 +14152,21 @@ function generateCode(ast, options) {
|
|
|
14134
14152
|
if (inlineFunctions.length > 0) {
|
|
14135
14153
|
lines.push("");
|
|
14136
14154
|
addLine();
|
|
14155
|
+
const emittedHelpers = /* @__PURE__ */ new Set();
|
|
14156
|
+
inlineFunctions.forEach((node) => {
|
|
14157
|
+
if (node.importSource) return;
|
|
14158
|
+
const helperText = production ? node.helperTextProduction ?? null : node.helperText ?? null;
|
|
14159
|
+
if (helperText && !emittedHelpers.has(helperText)) {
|
|
14160
|
+
emittedHelpers.add(helperText);
|
|
14161
|
+
lines.push(helperText);
|
|
14162
|
+
helperText.split("\n").forEach(() => addLine());
|
|
14163
|
+
lines.push("");
|
|
14164
|
+
addLine();
|
|
14165
|
+
}
|
|
14166
|
+
});
|
|
14137
14167
|
inlineFunctions.forEach((node) => {
|
|
14138
14168
|
if (node.importSource) return;
|
|
14139
|
-
const functionText = node.functionText;
|
|
14169
|
+
const functionText = production && node.functionTextProduction != null ? node.functionTextProduction : node.functionText;
|
|
14140
14170
|
if (functionText) {
|
|
14141
14171
|
const functionWithoutDecorators = removeDecorators(functionText);
|
|
14142
14172
|
if (node.sourceLocation) {
|
|
@@ -15258,12 +15288,62 @@ function generateInPlace(sourceCode, ast, options = {}) {
|
|
|
15258
15288
|
if (nodeType.sourceLocation?.file && path2.resolve(nodeType.sourceLocation.file) !== path2.resolve(ast.sourceFile)) {
|
|
15259
15289
|
continue;
|
|
15260
15290
|
}
|
|
15291
|
+
if (!nodeType.sourceLocation && nodeType.helperText != null) {
|
|
15292
|
+
continue;
|
|
15293
|
+
}
|
|
15261
15294
|
const nodeTypeResult = replaceNodeTypeJSDoc(result, nodeType);
|
|
15262
15295
|
if (nodeTypeResult.changed) {
|
|
15263
15296
|
result = nodeTypeResult.code;
|
|
15264
15297
|
hasChanges = true;
|
|
15265
15298
|
}
|
|
15266
15299
|
}
|
|
15300
|
+
const usedNodeTypes = new Set(ast.instances.map((i) => i.nodeType));
|
|
15301
|
+
const builtInNodes = ast.nodeTypes.filter(
|
|
15302
|
+
(nt2) => !nt2.sourceLocation && nt2.functionText && nt2.helperText != null && usedNodeTypes.has(nt2.name)
|
|
15303
|
+
);
|
|
15304
|
+
if (builtInNodes.length > 0) {
|
|
15305
|
+
const workflowFnPattern = new RegExp(
|
|
15306
|
+
`(/\\*\\*[\\s\\S]*?@flowWeaver\\s+workflow[\\s\\S]*?\\*/)\\s*\\n\\s*(?:export\\s+)?(?:async\\s+)?function\\s+${ast.functionName}\\b`
|
|
15307
|
+
);
|
|
15308
|
+
const match = result.match(workflowFnPattern);
|
|
15309
|
+
if (match && match.index !== void 0) {
|
|
15310
|
+
const insertionLines = [];
|
|
15311
|
+
const emittedHelpers = /* @__PURE__ */ new Set();
|
|
15312
|
+
for (const node of builtInNodes) {
|
|
15313
|
+
const helperText = production ? node.helperTextProduction ?? null : node.helperText ?? null;
|
|
15314
|
+
if (helperText && !emittedHelpers.has(helperText)) {
|
|
15315
|
+
emittedHelpers.add(helperText);
|
|
15316
|
+
insertionLines.push(helperText);
|
|
15317
|
+
insertionLines.push("");
|
|
15318
|
+
}
|
|
15319
|
+
}
|
|
15320
|
+
for (const node of builtInNodes) {
|
|
15321
|
+
const funcText = production && node.functionTextProduction != null ? node.functionTextProduction : node.functionText;
|
|
15322
|
+
if (funcText) {
|
|
15323
|
+
const portAnnotations = [];
|
|
15324
|
+
portAnnotations.push("/**");
|
|
15325
|
+
portAnnotations.push(` * @flowWeaver nodeType`);
|
|
15326
|
+
for (const [name, port] of Object.entries(node.inputs)) {
|
|
15327
|
+
if (name === "execute") continue;
|
|
15328
|
+
const optPrefix = port.optional ? "[" : "";
|
|
15329
|
+
const optSuffix = port.optional ? "]" : "";
|
|
15330
|
+
portAnnotations.push(` * @input ${optPrefix}${name}${optSuffix} - ${port.label || name}`);
|
|
15331
|
+
}
|
|
15332
|
+
for (const [name, port] of Object.entries(node.outputs)) {
|
|
15333
|
+
if (name === "onSuccess" || name === "onFailure") continue;
|
|
15334
|
+
portAnnotations.push(` * @output ${name} - ${port.label || name}`);
|
|
15335
|
+
}
|
|
15336
|
+
portAnnotations.push(" */");
|
|
15337
|
+
insertionLines.push(portAnnotations.join("\n"));
|
|
15338
|
+
insertionLines.push(funcText);
|
|
15339
|
+
insertionLines.push("");
|
|
15340
|
+
}
|
|
15341
|
+
}
|
|
15342
|
+
const insertionCode = insertionLines.join("\n");
|
|
15343
|
+
result = result.slice(0, match.index) + insertionCode + "\n" + result.slice(match.index);
|
|
15344
|
+
hasChanges = true;
|
|
15345
|
+
}
|
|
15346
|
+
}
|
|
15267
15347
|
const cleanupResult = removeOrphanedNodeTypeFunctions(result, ast, allWorkflows);
|
|
15268
15348
|
if (cleanupResult.changed) {
|
|
15269
15349
|
result = cleanupResult.code;
|
|
@@ -27243,6 +27323,306 @@ var init_coercion_types = __esm({
|
|
|
27243
27323
|
}
|
|
27244
27324
|
});
|
|
27245
27325
|
|
|
27326
|
+
// src/built-in-nodes/generated-registry.ts
|
|
27327
|
+
var BUILT_IN_NODE_TYPES;
|
|
27328
|
+
var init_generated_registry = __esm({
|
|
27329
|
+
"src/built-in-nodes/generated-registry.ts"() {
|
|
27330
|
+
"use strict";
|
|
27331
|
+
BUILT_IN_NODE_TYPES = [
|
|
27332
|
+
{
|
|
27333
|
+
type: "NodeType",
|
|
27334
|
+
name: "delay",
|
|
27335
|
+
functionName: "delay",
|
|
27336
|
+
isAsync: true,
|
|
27337
|
+
hasSuccessPort: true,
|
|
27338
|
+
hasFailurePort: true,
|
|
27339
|
+
executeWhen: "CONJUNCTION",
|
|
27340
|
+
variant: "FUNCTION",
|
|
27341
|
+
inputs: {
|
|
27342
|
+
execute: { dataType: "STEP", label: "Execute" },
|
|
27343
|
+
duration: { dataType: "STRING", label: 'Duration to sleep (e.g. "30s", "5m", "1h", "2d")', tsType: "string" }
|
|
27344
|
+
},
|
|
27345
|
+
outputs: {
|
|
27346
|
+
onSuccess: { dataType: "STEP", label: "On Success", isControlFlow: true },
|
|
27347
|
+
onFailure: { dataType: "STEP", label: "On Failure", isControlFlow: true, failure: true },
|
|
27348
|
+
elapsed: { dataType: "BOOLEAN", label: "Always true after sleep completes", tsType: "boolean" }
|
|
27349
|
+
},
|
|
27350
|
+
helperText: `
|
|
27351
|
+
function __fw_getMockConfig() {
|
|
27352
|
+
return globalThis.__fw_mocks__;
|
|
27353
|
+
}
|
|
27354
|
+
|
|
27355
|
+
function __fw_lookupMock(section, key) {
|
|
27356
|
+
if (!section)
|
|
27357
|
+
return undefined;
|
|
27358
|
+
const nodeId = globalThis.__fw_current_node_id__;
|
|
27359
|
+
if (nodeId) {
|
|
27360
|
+
const qualified = section[\`\${nodeId}:\${key}\`];
|
|
27361
|
+
if (qualified !== undefined)
|
|
27362
|
+
return qualified;
|
|
27363
|
+
}
|
|
27364
|
+
return section[key];
|
|
27365
|
+
}
|
|
27366
|
+
`.trim(),
|
|
27367
|
+
helperTextProduction: void 0,
|
|
27368
|
+
functionText: `
|
|
27369
|
+
async function delay(execute, duration) {
|
|
27370
|
+
if (!execute)
|
|
27371
|
+
return { onSuccess: false, onFailure: false, elapsed: false };
|
|
27372
|
+
const mocks = __fw_getMockConfig();
|
|
27373
|
+
if (mocks?.fast) {
|
|
27374
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
27375
|
+
}
|
|
27376
|
+
else {
|
|
27377
|
+
const ms = __fw_parseDuration(duration);
|
|
27378
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
27379
|
+
}
|
|
27380
|
+
return { onSuccess: true, onFailure: false, elapsed: true };
|
|
27381
|
+
}
|
|
27382
|
+
function __fw_parseDuration(duration) {
|
|
27383
|
+
const match = duration.match(/^(\\d+)(ms|s|m|h|d)$/);
|
|
27384
|
+
if (!match)
|
|
27385
|
+
return 0;
|
|
27386
|
+
const [, value, unit] = match;
|
|
27387
|
+
const multipliers = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000 };
|
|
27388
|
+
return parseInt(value) * (multipliers[unit] || 0);
|
|
27389
|
+
}
|
|
27390
|
+
`.trim(),
|
|
27391
|
+
functionTextProduction: `
|
|
27392
|
+
async function delay(execute, duration) {
|
|
27393
|
+
if (!execute)
|
|
27394
|
+
return { onSuccess: false, onFailure: false, elapsed: false };
|
|
27395
|
+
const ms = __fw_parseDuration(duration);
|
|
27396
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
27397
|
+
return { onSuccess: true, onFailure: false, elapsed: true };
|
|
27398
|
+
}
|
|
27399
|
+
function __fw_parseDuration(duration) {
|
|
27400
|
+
const match = duration.match(/^(\\d+)(ms|s|m|h|d)$/);
|
|
27401
|
+
if (!match)
|
|
27402
|
+
return 0;
|
|
27403
|
+
const [, value, unit] = match;
|
|
27404
|
+
const multipliers = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000 };
|
|
27405
|
+
return parseInt(value) * (multipliers[unit] || 0);
|
|
27406
|
+
}
|
|
27407
|
+
`.trim()
|
|
27408
|
+
},
|
|
27409
|
+
{
|
|
27410
|
+
type: "NodeType",
|
|
27411
|
+
name: "waitForEvent",
|
|
27412
|
+
functionName: "waitForEvent",
|
|
27413
|
+
isAsync: true,
|
|
27414
|
+
hasSuccessPort: true,
|
|
27415
|
+
hasFailurePort: true,
|
|
27416
|
+
executeWhen: "CONJUNCTION",
|
|
27417
|
+
variant: "FUNCTION",
|
|
27418
|
+
inputs: {
|
|
27419
|
+
execute: { dataType: "STEP", label: "Execute" },
|
|
27420
|
+
eventName: { dataType: "STRING", label: 'Event name to wait for (e.g. "app/approval.received")', tsType: "string" },
|
|
27421
|
+
match: { dataType: "STRING", label: 'Field to match between trigger and waited event (e.g. "data.requestId")', tsType: "string", optional: true },
|
|
27422
|
+
timeout: { dataType: "STRING", label: 'Max wait time (e.g. "24h", "7d"). Empty = no timeout', tsType: "string", optional: true }
|
|
27423
|
+
},
|
|
27424
|
+
outputs: {
|
|
27425
|
+
onSuccess: { dataType: "STEP", label: "On Success", isControlFlow: true },
|
|
27426
|
+
onFailure: { dataType: "STEP", label: "On Failure", isControlFlow: true, failure: true },
|
|
27427
|
+
eventData: { dataType: "OBJECT", label: "The received event's data payload", tsType: "object" }
|
|
27428
|
+
},
|
|
27429
|
+
helperText: `
|
|
27430
|
+
function __fw_getMockConfig() {
|
|
27431
|
+
return globalThis.__fw_mocks__;
|
|
27432
|
+
}
|
|
27433
|
+
|
|
27434
|
+
function __fw_lookupMock(section, key) {
|
|
27435
|
+
if (!section)
|
|
27436
|
+
return undefined;
|
|
27437
|
+
const nodeId = globalThis.__fw_current_node_id__;
|
|
27438
|
+
if (nodeId) {
|
|
27439
|
+
const qualified = section[\`\${nodeId}:\${key}\`];
|
|
27440
|
+
if (qualified !== undefined)
|
|
27441
|
+
return qualified;
|
|
27442
|
+
}
|
|
27443
|
+
return section[key];
|
|
27444
|
+
}
|
|
27445
|
+
`.trim(),
|
|
27446
|
+
helperTextProduction: void 0,
|
|
27447
|
+
functionText: `
|
|
27448
|
+
async function waitForEvent(execute, eventName, match, timeout) {
|
|
27449
|
+
if (!execute)
|
|
27450
|
+
return { onSuccess: false, onFailure: false, eventData: {} };
|
|
27451
|
+
const mocks = __fw_getMockConfig();
|
|
27452
|
+
if (mocks) {
|
|
27453
|
+
const mockData = __fw_lookupMock(mocks.events, eventName);
|
|
27454
|
+
if (mockData !== undefined) {
|
|
27455
|
+
return { onSuccess: true, onFailure: false, eventData: mockData };
|
|
27456
|
+
}
|
|
27457
|
+
return { onSuccess: false, onFailure: true, eventData: {} };
|
|
27458
|
+
}
|
|
27459
|
+
return { onSuccess: true, onFailure: false, eventData: {} };
|
|
27460
|
+
}
|
|
27461
|
+
`.trim(),
|
|
27462
|
+
functionTextProduction: `
|
|
27463
|
+
async function waitForEvent(execute, eventName, match, timeout) {
|
|
27464
|
+
if (!execute)
|
|
27465
|
+
return { onSuccess: false, onFailure: false, eventData: {} };
|
|
27466
|
+
return { onSuccess: true, onFailure: false, eventData: {} };
|
|
27467
|
+
}
|
|
27468
|
+
`.trim()
|
|
27469
|
+
},
|
|
27470
|
+
{
|
|
27471
|
+
type: "NodeType",
|
|
27472
|
+
name: "invokeWorkflow",
|
|
27473
|
+
functionName: "invokeWorkflow",
|
|
27474
|
+
isAsync: true,
|
|
27475
|
+
hasSuccessPort: true,
|
|
27476
|
+
hasFailurePort: true,
|
|
27477
|
+
executeWhen: "CONJUNCTION",
|
|
27478
|
+
variant: "FUNCTION",
|
|
27479
|
+
inputs: {
|
|
27480
|
+
execute: { dataType: "STEP", label: "Execute" },
|
|
27481
|
+
functionId: { dataType: "STRING", label: 'Function ID of the workflow to invoke (e.g. "my-service/sub-workflow")', tsType: "string" },
|
|
27482
|
+
payload: { dataType: "OBJECT", label: "Data to pass as event.data to the invoked function", tsType: "object" },
|
|
27483
|
+
timeout: { dataType: "STRING", label: 'Max wait time (e.g. "1h")', tsType: "string", optional: true }
|
|
27484
|
+
},
|
|
27485
|
+
outputs: {
|
|
27486
|
+
onSuccess: { dataType: "STEP", label: "On Success", isControlFlow: true },
|
|
27487
|
+
onFailure: { dataType: "STEP", label: "On Failure", isControlFlow: true, failure: true },
|
|
27488
|
+
result: { dataType: "OBJECT", label: "Return value from the invoked function", tsType: "object" }
|
|
27489
|
+
},
|
|
27490
|
+
helperText: `
|
|
27491
|
+
function __fw_getMockConfig() {
|
|
27492
|
+
return globalThis.__fw_mocks__;
|
|
27493
|
+
}
|
|
27494
|
+
|
|
27495
|
+
function __fw_lookupMock(section, key) {
|
|
27496
|
+
if (!section)
|
|
27497
|
+
return undefined;
|
|
27498
|
+
const nodeId = globalThis.__fw_current_node_id__;
|
|
27499
|
+
if (nodeId) {
|
|
27500
|
+
const qualified = section[\`\${nodeId}:\${key}\`];
|
|
27501
|
+
if (qualified !== undefined)
|
|
27502
|
+
return qualified;
|
|
27503
|
+
}
|
|
27504
|
+
return section[key];
|
|
27505
|
+
}
|
|
27506
|
+
`.trim(),
|
|
27507
|
+
helperTextProduction: void 0,
|
|
27508
|
+
functionText: `
|
|
27509
|
+
async function invokeWorkflow(execute, functionId, payload, timeout) {
|
|
27510
|
+
if (!execute)
|
|
27511
|
+
return { onSuccess: false, onFailure: false, result: {} };
|
|
27512
|
+
const mocks = __fw_getMockConfig();
|
|
27513
|
+
if (mocks) {
|
|
27514
|
+
const mockResult = __fw_lookupMock(mocks.invocations, functionId);
|
|
27515
|
+
if (mockResult !== undefined) {
|
|
27516
|
+
return { onSuccess: true, onFailure: false, result: mockResult };
|
|
27517
|
+
}
|
|
27518
|
+
return { onSuccess: false, onFailure: true, result: {} };
|
|
27519
|
+
}
|
|
27520
|
+
const registry = globalThis.__fw_workflow_registry__;
|
|
27521
|
+
if (registry?.[functionId]) {
|
|
27522
|
+
try {
|
|
27523
|
+
const result = await registry[functionId](true, payload);
|
|
27524
|
+
return { onSuccess: true, onFailure: false, result: result ?? {} };
|
|
27525
|
+
}
|
|
27526
|
+
catch {
|
|
27527
|
+
return { onSuccess: false, onFailure: true, result: {} };
|
|
27528
|
+
}
|
|
27529
|
+
}
|
|
27530
|
+
return { onSuccess: true, onFailure: false, result: {} };
|
|
27531
|
+
}
|
|
27532
|
+
`.trim(),
|
|
27533
|
+
functionTextProduction: `
|
|
27534
|
+
async function invokeWorkflow(execute, functionId, payload, timeout) {
|
|
27535
|
+
if (!execute)
|
|
27536
|
+
return { onSuccess: false, onFailure: false, result: {} };
|
|
27537
|
+
const registry = globalThis.__fw_workflow_registry__;
|
|
27538
|
+
if (registry?.[functionId]) {
|
|
27539
|
+
try {
|
|
27540
|
+
const result = await registry[functionId](true, payload);
|
|
27541
|
+
return { onSuccess: true, onFailure: false, result: result ?? {} };
|
|
27542
|
+
}
|
|
27543
|
+
catch {
|
|
27544
|
+
return { onSuccess: false, onFailure: true, result: {} };
|
|
27545
|
+
}
|
|
27546
|
+
}
|
|
27547
|
+
return { onSuccess: true, onFailure: false, result: {} };
|
|
27548
|
+
}
|
|
27549
|
+
`.trim()
|
|
27550
|
+
},
|
|
27551
|
+
{
|
|
27552
|
+
type: "NodeType",
|
|
27553
|
+
name: "waitForAgent",
|
|
27554
|
+
functionName: "waitForAgent",
|
|
27555
|
+
isAsync: true,
|
|
27556
|
+
hasSuccessPort: true,
|
|
27557
|
+
hasFailurePort: true,
|
|
27558
|
+
executeWhen: "CONJUNCTION",
|
|
27559
|
+
variant: "FUNCTION",
|
|
27560
|
+
inputs: {
|
|
27561
|
+
execute: { dataType: "STEP", label: "Execute" },
|
|
27562
|
+
agentId: { dataType: "STRING", label: "Agent/task identifier", tsType: "string" },
|
|
27563
|
+
context: { dataType: "OBJECT", label: "Context data to send to the agent", tsType: "object" },
|
|
27564
|
+
prompt: { dataType: "STRING", label: "Message to display when requesting input", tsType: "string", optional: true }
|
|
27565
|
+
},
|
|
27566
|
+
outputs: {
|
|
27567
|
+
onSuccess: { dataType: "STEP", label: "On Success", isControlFlow: true },
|
|
27568
|
+
onFailure: { dataType: "STEP", label: "On Failure", isControlFlow: true, failure: true },
|
|
27569
|
+
agentResult: { dataType: "OBJECT", label: "Result returned by the agent", tsType: "object" }
|
|
27570
|
+
},
|
|
27571
|
+
helperText: `
|
|
27572
|
+
function __fw_getMockConfig() {
|
|
27573
|
+
return globalThis.__fw_mocks__;
|
|
27574
|
+
}
|
|
27575
|
+
|
|
27576
|
+
function __fw_lookupMock(section, key) {
|
|
27577
|
+
if (!section)
|
|
27578
|
+
return undefined;
|
|
27579
|
+
const nodeId = globalThis.__fw_current_node_id__;
|
|
27580
|
+
if (nodeId) {
|
|
27581
|
+
const qualified = section[\`\${nodeId}:\${key}\`];
|
|
27582
|
+
if (qualified !== undefined)
|
|
27583
|
+
return qualified;
|
|
27584
|
+
}
|
|
27585
|
+
return section[key];
|
|
27586
|
+
}
|
|
27587
|
+
`.trim(),
|
|
27588
|
+
helperTextProduction: void 0,
|
|
27589
|
+
functionText: `
|
|
27590
|
+
async function waitForAgent(execute, agentId, context, prompt) {
|
|
27591
|
+
if (!execute)
|
|
27592
|
+
return { onSuccess: false, onFailure: false, agentResult: {} };
|
|
27593
|
+
const mocks = __fw_getMockConfig();
|
|
27594
|
+
const mockResult = __fw_lookupMock(mocks?.agents, agentId);
|
|
27595
|
+
if (mockResult !== undefined) {
|
|
27596
|
+
return { onSuccess: true, onFailure: false, agentResult: mockResult };
|
|
27597
|
+
}
|
|
27598
|
+
if (mocks?.agents) {
|
|
27599
|
+
return { onSuccess: false, onFailure: true, agentResult: {} };
|
|
27600
|
+
}
|
|
27601
|
+
const channel = globalThis.__fw_agent_channel__;
|
|
27602
|
+
if (channel) {
|
|
27603
|
+
const result = await channel.request({ agentId, context, prompt });
|
|
27604
|
+
return { onSuccess: true, onFailure: false, agentResult: result };
|
|
27605
|
+
}
|
|
27606
|
+
return { onSuccess: true, onFailure: false, agentResult: {} };
|
|
27607
|
+
}
|
|
27608
|
+
`.trim(),
|
|
27609
|
+
functionTextProduction: `
|
|
27610
|
+
async function waitForAgent(execute, agentId, context, prompt) {
|
|
27611
|
+
if (!execute)
|
|
27612
|
+
return { onSuccess: false, onFailure: false, agentResult: {} };
|
|
27613
|
+
const channel = globalThis.__fw_agent_channel__;
|
|
27614
|
+
if (channel) {
|
|
27615
|
+
const result = await channel.request({ agentId, context, prompt });
|
|
27616
|
+
return { onSuccess: true, onFailure: false, agentResult: result };
|
|
27617
|
+
}
|
|
27618
|
+
return { onSuccess: true, onFailure: false, agentResult: {} };
|
|
27619
|
+
}
|
|
27620
|
+
`.trim()
|
|
27621
|
+
}
|
|
27622
|
+
];
|
|
27623
|
+
}
|
|
27624
|
+
});
|
|
27625
|
+
|
|
27246
27626
|
// src/parser/tag-registry.ts
|
|
27247
27627
|
var TagHandlerRegistry, tagHandlerRegistry;
|
|
27248
27628
|
var init_tag_registry = __esm({
|
|
@@ -27571,6 +27951,7 @@ var init_parser2 = __esm({
|
|
|
27571
27951
|
init_shared_project();
|
|
27572
27952
|
init_lru_cache();
|
|
27573
27953
|
init_coercion_types();
|
|
27954
|
+
init_generated_registry();
|
|
27574
27955
|
init_tag_registry();
|
|
27575
27956
|
AnnotationParser = class {
|
|
27576
27957
|
project;
|
|
@@ -27714,7 +28095,7 @@ var init_parser2 = __esm({
|
|
|
27714
28095
|
}
|
|
27715
28096
|
}
|
|
27716
28097
|
}
|
|
27717
|
-
const inferredNodeTypes = this.inferNodeTypesFromUnannotated(sourceFile, nodeTypes);
|
|
28098
|
+
const inferredNodeTypes = this.inferNodeTypesFromUnannotated(sourceFile, nodeTypes, localNodeTypes, warnings);
|
|
27718
28099
|
nodeTypes.push(...inferredNodeTypes);
|
|
27719
28100
|
const workflows = this.extractWorkflows(sourceFile, nodeTypes, filePath, errors2, warnings);
|
|
27720
28101
|
const patterns = this.extractPatterns(sourceFile, nodeTypes, filePath, errors2, warnings);
|
|
@@ -27754,7 +28135,7 @@ var init_parser2 = __esm({
|
|
|
27754
28135
|
const workflowSignatures = this.extractWorkflowSignatures(sourceFile, virtualPath, warnings);
|
|
27755
28136
|
const sameFileWorkflowNodeTypes = workflowSignatures.map((wf) => this.workflowToNodeType(wf));
|
|
27756
28137
|
const nodeTypes = [...localNodeTypes, ...sameFileWorkflowNodeTypes];
|
|
27757
|
-
const inferredNodeTypes = this.inferNodeTypesFromUnannotated(sourceFile, nodeTypes);
|
|
28138
|
+
const inferredNodeTypes = this.inferNodeTypesFromUnannotated(sourceFile, nodeTypes, localNodeTypes, warnings);
|
|
27758
28139
|
nodeTypes.push(...inferredNodeTypes);
|
|
27759
28140
|
const workflows = this.extractWorkflows(sourceFile, nodeTypes, virtualPath, errors2, warnings);
|
|
27760
28141
|
const patterns = this.extractPatterns(sourceFile, nodeTypes, virtualPath, errors2, warnings);
|
|
@@ -27986,7 +28367,7 @@ var init_parser2 = __esm({
|
|
|
27986
28367
|
if (imp.importSource.startsWith(".")) {
|
|
27987
28368
|
return this.resolveLocalImportAnnotation(imp, currentDir, warnings);
|
|
27988
28369
|
} else {
|
|
27989
|
-
return this.resolveNpmImportAnnotation(imp, currentDir);
|
|
28370
|
+
return this.resolveNpmImportAnnotation(imp, currentDir, warnings);
|
|
27990
28371
|
}
|
|
27991
28372
|
}
|
|
27992
28373
|
/**
|
|
@@ -28031,7 +28412,7 @@ var init_parser2 = __esm({
|
|
|
28031
28412
|
/**
|
|
28032
28413
|
* Resolve an npm package @fwImport to a node type by reading .d.ts declarations.
|
|
28033
28414
|
*/
|
|
28034
|
-
resolveNpmImportAnnotation(imp, currentDir) {
|
|
28415
|
+
resolveNpmImportAnnotation(imp, currentDir, warnings) {
|
|
28035
28416
|
const cacheKey = `npm:${imp.importSource}`;
|
|
28036
28417
|
if (this.importCache.has(cacheKey)) {
|
|
28037
28418
|
const cached2 = this.importCache.get(cacheKey);
|
|
@@ -28055,6 +28436,9 @@ var init_parser2 = __esm({
|
|
|
28055
28436
|
}
|
|
28056
28437
|
const dtsPath = resolvePackageTypesPath(imp.importSource, currentDir);
|
|
28057
28438
|
if (!dtsPath) {
|
|
28439
|
+
warnings.push(
|
|
28440
|
+
`@fwImport: Package "${imp.importSource}" has no type declarations (.d.ts). Install @types/${imp.importSource} or add a local wrapper with @flowWeaver nodeType annotations.`
|
|
28441
|
+
);
|
|
28058
28442
|
return this.createImportStub(imp);
|
|
28059
28443
|
}
|
|
28060
28444
|
try {
|
|
@@ -28084,7 +28468,13 @@ var init_parser2 = __esm({
|
|
|
28084
28468
|
if (found) {
|
|
28085
28469
|
return { ...found, name: imp.name, importSource: imp.importSource };
|
|
28086
28470
|
}
|
|
28087
|
-
|
|
28471
|
+
warnings.push(
|
|
28472
|
+
`@fwImport: Function "${imp.functionName}" not found in type declarations for "${imp.importSource}". Available exports: ${allNodeTypes.map((nt2) => nt2.functionName).join(", ") || "(none)"}.`
|
|
28473
|
+
);
|
|
28474
|
+
} catch (err) {
|
|
28475
|
+
warnings.push(
|
|
28476
|
+
`@fwImport: Failed to parse type declarations for "${imp.importSource}": ${err.message}. Node "${imp.name}" will use a generic stub.`
|
|
28477
|
+
);
|
|
28088
28478
|
}
|
|
28089
28479
|
return this.createImportStub(imp);
|
|
28090
28480
|
}
|
|
@@ -28383,6 +28773,18 @@ ${fn.getText()}` : fn.getText();
|
|
|
28383
28773
|
const importedNpmNodeTypes = (config2.imports || []).map(
|
|
28384
28774
|
(imp) => this.resolveImportAnnotation(imp, filePath, warnings)
|
|
28385
28775
|
);
|
|
28776
|
+
for (const nt2 of importedNpmNodeTypes) {
|
|
28777
|
+
const dataInputs = Object.keys(nt2.inputs).filter((p) => p !== "execute");
|
|
28778
|
+
const nonControlOutputs = Object.keys(nt2.outputs).filter(
|
|
28779
|
+
(p) => p !== "onSuccess" && p !== "onFailure"
|
|
28780
|
+
);
|
|
28781
|
+
const isStubOnly = nonControlOutputs.length === 1 && nonControlOutputs[0] === "result" && nt2.outputs.result?.dataType === "ANY";
|
|
28782
|
+
if (dataInputs.length === 0 && isStubOnly) {
|
|
28783
|
+
warnings.push(
|
|
28784
|
+
`Could not infer ports for "${nt2.functionName}" from "${nt2.importSource}". Wrap it in a local function with @flowWeaver nodeType annotations instead.`
|
|
28785
|
+
);
|
|
28786
|
+
}
|
|
28787
|
+
}
|
|
28386
28788
|
const allAvailableNodeTypes = [...availableNodeTypes, ...importedNpmNodeTypes];
|
|
28387
28789
|
const instances = (config2.instances || []).map((inst) => {
|
|
28388
28790
|
const nodeTypeExists = allAvailableNodeTypes.some(
|
|
@@ -28733,7 +29135,7 @@ ${fn.getText()}` : fn.getText();
|
|
|
28733
29135
|
* nodeType annotation, we infer an expression node type from its TypeScript
|
|
28734
29136
|
* signature. Phase 1: same-file functions only.
|
|
28735
29137
|
*/
|
|
28736
|
-
inferNodeTypesFromUnannotated(sourceFile, existingNodeTypes) {
|
|
29138
|
+
inferNodeTypesFromUnannotated(sourceFile, existingNodeTypes, localNodeTypes, warnings) {
|
|
28737
29139
|
const allFunctions = extractFunctionLikes(sourceFile);
|
|
28738
29140
|
const referencedTypes = /* @__PURE__ */ new Set();
|
|
28739
29141
|
for (const fn of allFunctions) {
|
|
@@ -28757,8 +29159,24 @@ ${fn.getText()}` : fn.getText();
|
|
|
28757
29159
|
if (unresolvedTypes.size === 0) return [];
|
|
28758
29160
|
const inferredNodeTypes = [];
|
|
28759
29161
|
const alreadyInferred = /* @__PURE__ */ new Set();
|
|
29162
|
+
const builtInByName = new Map(BUILT_IN_NODE_TYPES.map((nt2) => [nt2.name, nt2]));
|
|
29163
|
+
const annotatedNames = new Set(localNodeTypes.map((nt2) => nt2.functionName));
|
|
28760
29164
|
for (const unresolvedType of unresolvedTypes) {
|
|
28761
29165
|
if (alreadyInferred.has(unresolvedType)) continue;
|
|
29166
|
+
const builtIn = builtInByName.get(unresolvedType);
|
|
29167
|
+
if (builtIn) {
|
|
29168
|
+
inferredNodeTypes.push(builtIn);
|
|
29169
|
+
alreadyInferred.add(unresolvedType);
|
|
29170
|
+
if (!annotatedNames.has(unresolvedType)) {
|
|
29171
|
+
const shadowFn = allFunctions.find((fn) => fn.getName() === unresolvedType && !this.hasFlowWeaverAnnotation(fn));
|
|
29172
|
+
if (shadowFn) {
|
|
29173
|
+
warnings.push(
|
|
29174
|
+
`Function '${unresolvedType}' exists in this file but is not annotated with @flowWeaver nodeType. The built-in '${unresolvedType}' will be used instead. Add @flowWeaver nodeType to use your version.`
|
|
29175
|
+
);
|
|
29176
|
+
}
|
|
29177
|
+
}
|
|
29178
|
+
continue;
|
|
29179
|
+
}
|
|
28762
29180
|
const matchedFn = allFunctions.find((fn) => {
|
|
28763
29181
|
if (fn.getName() !== unresolvedType) return false;
|
|
28764
29182
|
return !this.hasFlowWeaverAnnotation(fn);
|
|
@@ -29005,6 +29423,10 @@ ${fn.getText()}` : fn.getText();
|
|
|
29005
29423
|
const nextInputs = getInputPorts(nextId);
|
|
29006
29424
|
for (const [inputName] of Object.entries(nextInputs)) {
|
|
29007
29425
|
if (isControlFlowPort(inputName)) continue;
|
|
29426
|
+
const alreadyConnected = connections.some(
|
|
29427
|
+
(c) => c.to.node === nextId && c.to.port === inputName
|
|
29428
|
+
);
|
|
29429
|
+
if (alreadyConnected) continue;
|
|
29008
29430
|
for (let j2 = i; j2 >= 0; j2--) {
|
|
29009
29431
|
const ancestorId = steps[j2].node;
|
|
29010
29432
|
const ancestorOutputs = getOutputPorts(ancestorId);
|
|
@@ -37919,7 +38341,7 @@ function getDependents(ast, nodeId) {
|
|
|
37919
38341
|
});
|
|
37920
38342
|
return Array.from(dependents);
|
|
37921
38343
|
}
|
|
37922
|
-
function getTopologicalOrder(ast) {
|
|
38344
|
+
function getTopologicalOrder(ast, options) {
|
|
37923
38345
|
const mainInstances = getMainFlowInstances(ast);
|
|
37924
38346
|
const mainConnections = getMainFlowConnections(ast);
|
|
37925
38347
|
const inDegree = /* @__PURE__ */ new Map();
|
|
@@ -37958,6 +38380,30 @@ function getTopologicalOrder(ast) {
|
|
|
37958
38380
|
if (result.length !== mainInstances.length) {
|
|
37959
38381
|
throw new Error("Cannot compute topological order: workflow contains cycles");
|
|
37960
38382
|
}
|
|
38383
|
+
if (options?.includeScopedChildren) {
|
|
38384
|
+
const scopedChildren = ast.instances.filter(
|
|
38385
|
+
(inst) => isPerPortScopedChild(inst, ast, ast.nodeTypes)
|
|
38386
|
+
);
|
|
38387
|
+
const expanded = [];
|
|
38388
|
+
const scopedByParent = /* @__PURE__ */ new Map();
|
|
38389
|
+
for (const child of scopedChildren) {
|
|
38390
|
+
if (child.parent) {
|
|
38391
|
+
const parentId = child.parent.id;
|
|
38392
|
+
if (!scopedByParent.has(parentId)) {
|
|
38393
|
+
scopedByParent.set(parentId, []);
|
|
38394
|
+
}
|
|
38395
|
+
scopedByParent.get(parentId).push(child.id);
|
|
38396
|
+
}
|
|
38397
|
+
}
|
|
38398
|
+
for (const nodeId of result) {
|
|
38399
|
+
expanded.push(nodeId);
|
|
38400
|
+
const children = scopedByParent.get(nodeId);
|
|
38401
|
+
if (children) {
|
|
38402
|
+
expanded.push(...children);
|
|
38403
|
+
}
|
|
38404
|
+
}
|
|
38405
|
+
return expanded;
|
|
38406
|
+
}
|
|
37961
38407
|
return result;
|
|
37962
38408
|
}
|
|
37963
38409
|
function findIsolatedNodes(ast) {
|
|
@@ -58608,9 +59054,9 @@ function printNocodeGuidance(_projectName) {
|
|
|
58608
59054
|
logger.newline();
|
|
58609
59055
|
logger.log(` ${logger.bold("Useful commands")}`);
|
|
58610
59056
|
logger.newline();
|
|
58611
|
-
logger.log(` fw run src/*.ts ${logger.dim("Run your workflow")}`);
|
|
58612
|
-
logger.log(` fw diagram src/*.ts ${logger.dim("See a visual diagram")}`);
|
|
58613
|
-
logger.log(` fw mcp-setup ${logger.dim("Connect more AI editors")}`);
|
|
59057
|
+
logger.log(` npx fw run src/*.ts ${logger.dim("Run your workflow")}`);
|
|
59058
|
+
logger.log(` npx fw diagram src/*.ts ${logger.dim("See a visual diagram")}`);
|
|
59059
|
+
logger.log(` npx fw mcp-setup ${logger.dim("Connect more AI editors")}`);
|
|
58614
59060
|
}
|
|
58615
59061
|
function printVibecoderGuidance() {
|
|
58616
59062
|
logger.newline();
|
|
@@ -58628,17 +59074,17 @@ function printLowcodeGuidance() {
|
|
|
58628
59074
|
logger.newline();
|
|
58629
59075
|
logger.log(` ${logger.bold("Explore and customize")}`);
|
|
58630
59076
|
logger.newline();
|
|
58631
|
-
logger.log(` fw templates ${logger.dim("List all 16 workflow templates")}`);
|
|
58632
|
-
logger.log(` fw describe src/*.ts ${logger.dim("See the workflow structure")}`);
|
|
58633
|
-
logger.log(` fw docs annotations ${logger.dim("Annotation reference")}`);
|
|
59077
|
+
logger.log(` npx fw templates ${logger.dim("List all 16 workflow templates")}`);
|
|
59078
|
+
logger.log(` npx fw describe src/*.ts ${logger.dim("See the workflow structure")}`);
|
|
59079
|
+
logger.log(` npx fw docs annotations ${logger.dim("Annotation reference")}`);
|
|
58634
59080
|
logger.newline();
|
|
58635
59081
|
logger.log(` Your project includes an example in ${logger.highlight("examples/")} to study.`);
|
|
58636
59082
|
logger.log(` With MCP connected, AI can help modify nodes and connections.`);
|
|
58637
59083
|
}
|
|
58638
59084
|
function printExpertGuidance() {
|
|
58639
59085
|
logger.newline();
|
|
58640
|
-
logger.log(` fw mcp-setup ${logger.dim("Connect AI editors (Claude, Cursor, VS Code)")}`);
|
|
58641
|
-
logger.log(` fw docs ${logger.dim("Browse reference docs")}`);
|
|
59086
|
+
logger.log(` npx fw mcp-setup ${logger.dim("Connect AI editors (Claude, Cursor, VS Code)")}`);
|
|
59087
|
+
logger.log(` npx fw docs ${logger.dim("Browse reference docs")}`);
|
|
58642
59088
|
}
|
|
58643
59089
|
function pad(displayName, width) {
|
|
58644
59090
|
const padding = Math.max(1, width - displayName.length);
|
|
@@ -59588,16 +60034,19 @@ ${workflowCode}`;
|
|
|
59588
60034
|
"",
|
|
59589
60035
|
`import { ${workflowName} } from './${workflowJsFile}';`,
|
|
59590
60036
|
"",
|
|
59591
|
-
"
|
|
59592
|
-
` const result = ${workflowName}(true, { data: { message: 'hello world' } });`,
|
|
59593
|
-
" console.log(result);",
|
|
59594
|
-
"}
|
|
60037
|
+
"async function main() {",
|
|
60038
|
+
` const result = await ${workflowName}(true, { data: { message: 'hello world' } });`,
|
|
60039
|
+
" console.log(JSON.stringify(result, null, 2));",
|
|
60040
|
+
"}",
|
|
60041
|
+
"",
|
|
60042
|
+
"main().catch((e) => {",
|
|
59595
60043
|
" if (e instanceof Error && e.message.startsWith('Compile with:')) {",
|
|
59596
60044
|
" console.error('Workflow not compiled yet. Run: npm run dev');",
|
|
59597
60045
|
" process.exit(1);",
|
|
59598
60046
|
" }",
|
|
59599
|
-
"
|
|
59600
|
-
"
|
|
60047
|
+
" console.error(e);",
|
|
60048
|
+
" process.exit(1);",
|
|
60049
|
+
"});",
|
|
59601
60050
|
""
|
|
59602
60051
|
].join("\n");
|
|
59603
60052
|
} else {
|
|
@@ -59613,16 +60062,19 @@ ${workflowCode}`;
|
|
|
59613
60062
|
"",
|
|
59614
60063
|
`const { ${workflowName} } = require('./${workflowJsFile}');`,
|
|
59615
60064
|
"",
|
|
59616
|
-
"
|
|
59617
|
-
` const result = ${workflowName}(true, { data: { message: 'hello world' } });`,
|
|
59618
|
-
" console.log(result);",
|
|
59619
|
-
"}
|
|
60065
|
+
"async function main() {",
|
|
60066
|
+
` const result = await ${workflowName}(true, { data: { message: 'hello world' } });`,
|
|
60067
|
+
" console.log(JSON.stringify(result, null, 2));",
|
|
60068
|
+
"}",
|
|
60069
|
+
"",
|
|
60070
|
+
"main().catch((e) => {",
|
|
59620
60071
|
" if (e instanceof Error && e.message.startsWith('Compile with:')) {",
|
|
59621
60072
|
" console.error('Workflow not compiled yet. Run: npm run dev');",
|
|
59622
60073
|
" process.exit(1);",
|
|
59623
60074
|
" }",
|
|
59624
|
-
"
|
|
59625
|
-
"
|
|
60075
|
+
" console.error(e);",
|
|
60076
|
+
" process.exit(1);",
|
|
60077
|
+
"});",
|
|
59626
60078
|
""
|
|
59627
60079
|
].join("\n");
|
|
59628
60080
|
}
|
|
@@ -84560,6 +85012,13 @@ async function runCommandInner(input, options) {
|
|
|
84560
85012
|
logger.newline();
|
|
84561
85013
|
logger.section("Result");
|
|
84562
85014
|
logger.log(JSON.stringify(result.result, null, 2));
|
|
85015
|
+
const resultObj = result.result;
|
|
85016
|
+
if (resultObj?.onFailure === true && !options.params && !options.paramsFile) {
|
|
85017
|
+
logger.newline();
|
|
85018
|
+
logger.warn(
|
|
85019
|
+
"Tip: use --params to provide input. Run `fw describe <file>` to see expected inputs."
|
|
85020
|
+
);
|
|
85021
|
+
}
|
|
84563
85022
|
if (options.trace && !options.stream && result.trace && result.trace.length > 0) {
|
|
84564
85023
|
logger.newline();
|
|
84565
85024
|
logger.section("Trace");
|
|
@@ -88468,7 +88927,7 @@ function parseIntStrict(value) {
|
|
|
88468
88927
|
// src/cli/index.ts
|
|
88469
88928
|
init_logger();
|
|
88470
88929
|
init_error_utils();
|
|
88471
|
-
var version2 = true ? "0.
|
|
88930
|
+
var version2 = true ? "0.29.0" : "0.0.0-dev";
|
|
88472
88931
|
var program2 = new Command();
|
|
88473
88932
|
program2.name("fw").description("Flow Weaver Annotations - Compile and validate workflow files").option("-v, --version", "Output the current version").option("--no-color", "Disable colors").option("--color", "Force colors").on("option:version", () => {
|
|
88474
88933
|
logger.banner(version2);
|