@synergenius/flow-weaver 0.20.2 → 0.20.4

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.
@@ -38,6 +38,23 @@ export function validateWorkflow(ast, options) {
38
38
  }
39
39
  }
40
40
  }
41
+ // Filter warnings from additional rules through per-instance suppressWarnings
42
+ // (core validator already filters its own warnings, but agent/registry rules
43
+ // run after the core validator and need the same treatment)
44
+ const suppressMap = new Map();
45
+ for (const inst of ast.instances) {
46
+ if (inst.config?.suppressWarnings?.length) {
47
+ suppressMap.set(inst.id, new Set(inst.config.suppressWarnings));
48
+ }
49
+ }
50
+ if (suppressMap.size > 0) {
51
+ result.warnings = result.warnings.filter((w) => {
52
+ if (!w.node)
53
+ return true;
54
+ const codes = suppressMap.get(w.node);
55
+ return !codes || !codes.has(w.code);
56
+ });
57
+ }
41
58
  // Re-evaluate validity
42
59
  result.valid = result.errors.length === 0;
43
60
  return result;
@@ -9671,7 +9671,7 @@ var VERSION;
9671
9671
  var init_generated_version = __esm({
9672
9672
  "src/generated-version.ts"() {
9673
9673
  "use strict";
9674
- VERSION = "0.20.2";
9674
+ VERSION = "0.20.4";
9675
9675
  }
9676
9676
  });
9677
9677
 
@@ -34482,7 +34482,7 @@ var init_jsdoc_parser = __esm({
34482
34482
  } else if (func) {
34483
34483
  const returnType = func.getReturnType();
34484
34484
  const returnTypeText = returnType.getText();
34485
- const fieldMatch = returnTypeText.match(new RegExp(`${name}\\s*:\\s*([^;},]+)`));
34485
+ const fieldMatch = returnTypeText.match(new RegExp(`${name}\\??\\s*:\\s*([^;},]+)`));
34486
34486
  if (fieldMatch) {
34487
34487
  type2 = inferDataTypeFromTS(fieldMatch[1].trim());
34488
34488
  } else {
@@ -34527,7 +34527,7 @@ var init_jsdoc_parser = __esm({
34527
34527
  const paramTypeText = paramType.getText();
34528
34528
  const isCatchAllRecord = /^Record<string,\s*(never|any|unknown)>$/.test(paramTypeText) || paramTypeText === "{}" || /^\{\s*\[[\w]+:\s*string\]:\s*(never|any|unknown);\s*\}$/.test(paramTypeText);
34529
34529
  if (!isCatchAllRecord) {
34530
- const fieldMatch = paramTypeText.match(new RegExp(`${name}\\s*:\\s*([^;},]+)`));
34530
+ const fieldMatch = paramTypeText.match(new RegExp(`${name}\\??\\s*:\\s*([^;},]+)`));
34531
34531
  if (fieldMatch) {
34532
34532
  type2 = inferDataTypeFromTS(fieldMatch[1].trim());
34533
34533
  } else {
@@ -39988,6 +39988,19 @@ function validateWorkflow(ast, options) {
39988
39988
  }
39989
39989
  }
39990
39990
  }
39991
+ const suppressMap = /* @__PURE__ */ new Map();
39992
+ for (const inst of ast.instances) {
39993
+ if (inst.config?.suppressWarnings?.length) {
39994
+ suppressMap.set(inst.id, new Set(inst.config.suppressWarnings));
39995
+ }
39996
+ }
39997
+ if (suppressMap.size > 0) {
39998
+ result.warnings = result.warnings.filter((w) => {
39999
+ if (!w.node) return true;
40000
+ const codes = suppressMap.get(w.node);
40001
+ return !codes || !codes.has(w.code);
40002
+ });
40003
+ }
39991
40004
  result.valid = result.errors.length === 0;
39992
40005
  return result;
39993
40006
  }
@@ -46215,12 +46228,13 @@ function outputResult(data: any): { result: any } {
46215
46228
 
46216
46229
  /**
46217
46230
  * @flowWeaver workflow
46218
- * @node validator validateData [position: -300 0]
46219
- * @node transformer transformData [position: 0 0]
46220
- * @node outputter outputResult [position: 300 0]
46231
+ * @node validator validateData [position: -300 0] [color: "green"] [icon: "verified"] [suppress: "UNUSED_OUTPUT_PORT"]
46232
+ * @node transformer transformData [position: 0 0] [color: "blue"] [icon: "sync"]
46233
+ * @node outputter outputResult [position: 300 0] [color: "cyan"] [icon: "inventory"]
46221
46234
  * @position Start -600 0
46222
46235
  * @position Exit 600 0
46223
46236
  * @path Start -> validator -> transformer -> outputter -> Exit
46237
+ * @connect outputter.result -> Exit.result
46224
46238
  * @connect validator.onFailure -> Exit.onFailure
46225
46239
  * @connect validator.error -> Exit.error
46226
46240
  * @param execute [order:0] - Execute
@@ -46260,9 +46274,11 @@ function ${name}(${inputPortName}: any): { ${outputPortName}: any } {
46260
46274
  });
46261
46275
  const spacing = 300;
46262
46276
  const startX = -(nodeNames.length * (spacing / 2) + spacing / 2);
46277
+ const stepColors = ["green", "blue", "cyan", "orange", "purple", "teal", "pink", "yellow"];
46263
46278
  const nodeAnnotations = nodeNames.map((name, i) => {
46264
46279
  const x = startX + (i + 1) * spacing;
46265
- return ` * @node step${i} ${name} [position: ${x} 0]`;
46280
+ const color = stepColors[i % stepColors.length];
46281
+ return ` * @node step${i} ${name} [position: ${x} 0] [color: "${color}"] [icon: "settings"]`;
46266
46282
  }).join("\n");
46267
46283
  const positionAnnotations = [
46268
46284
  ` * @position Start ${startX} 0`,
@@ -46460,9 +46476,9 @@ function aggregateResults(
46460
46476
 
46461
46477
  /**
46462
46478
  * @flowWeaver workflow
46463
- * @node iterator forEachItem [size: 300 200] [position: -90 0]
46464
- * @node processor processItem iterator.processItem [position: 90 0]
46465
- * @node aggregator aggregateResults [position: 270 0]
46479
+ * @node iterator forEachItem [position: -90 0] [color: "purple"] [icon: "repeat"]
46480
+ * @node processor processItem iterator.processItem [color: "blue"] [icon: "settings"]
46481
+ * @node aggregator aggregateResults [position: 270 0] [color: "teal"] [icon: "inventory"]
46466
46482
  * @position Start -450 0
46467
46483
  * @position Exit 450 0
46468
46484
  * @connect Start.execute -> iterator.execute
@@ -46600,9 +46616,9 @@ function handleFailure(
46600
46616
 
46601
46617
  /**
46602
46618
  * @flowWeaver workflow
46603
- * @node router evaluateCondition [position: -180 0]
46604
- * @node successHandler handleSuccess [position: 90 -90]
46605
- * @node failureHandler handleFailure [position: 90 90]
46619
+ * @node router evaluateCondition [position: -180 0] [color: "orange"] [icon: "altRoute"] [suppress: "UNUSED_OUTPUT_PORT"]
46620
+ * @node successHandler handleSuccess [position: 90 -90] [color: "green"] [icon: "checkCircle"]
46621
+ * @node failureHandler handleFailure [position: 90 90] [color: "red"] [icon: "error"]
46606
46622
  * @position Start -450 0
46607
46623
  * @position Exit 360 0
46608
46624
  * @connect Start.execute -> router.execute
@@ -47267,9 +47283,9 @@ async function executeTools(
47267
47283
  * AI Agent that uses tools to accomplish tasks
47268
47284
  *
47269
47285
  * @flowWeaver workflow
47270
- * @node loop agentLoop [size: 450 350] [position: -180 0]
47271
- * @node llm callLLM loop.iteration [position: -40 100]
47272
- * @node tools executeTools loop.iteration [position: 120 200]
47286
+ * @node loop agentLoop [position: -180 0] [color: "purple"] [icon: "smartToy"]
47287
+ * @node llm callLLM loop.iteration [color: "blue"] [icon: "psychology"]
47288
+ * @node tools executeTools loop.iteration [color: "orange"] [icon: "build"] [suppress: "AGENT_UNGUARDED_TOOL_EXECUTOR"]
47273
47289
  * @position Start -450 0
47274
47290
  * @position Exit 360 0
47275
47291
  * @connect Start.execute -> loop.execute
@@ -47561,25 +47577,25 @@ async function act(
47561
47577
  * ReAct Agent \u2014 iterative Thought\u2192Action\u2192Observation loop
47562
47578
  *
47563
47579
  * @flowWeaver workflow
47564
- * @node loop reactLoop [size: 450 250] [position: -150 0]
47565
- * @node thinking think loop.step [position: -80 30]
47566
- * @node acting act loop.step [position: 130 30]
47580
+ * @node loop reactLoop [position: -150 0] [color: "purple"] [icon: "psychology"]
47581
+ * @node thinking think loop.step [color: "blue"] [icon: "autoAwesome"]
47582
+ * @node acting act loop.step [color: "orange"] [icon: "bolt"]
47567
47583
  * @position Start -400 0
47568
47584
  * @position Exit 350 0
47569
47585
  * @connect Start.execute -> loop.execute
47570
47586
  * @connect Start.task -> loop.task
47571
- * @connect loop.start -> thinking.execute
47572
- * @connect loop.messages -> thinking.messages
47587
+ * @connect loop.start:step -> thinking.execute
47588
+ * @connect loop.messages:step -> thinking.messages
47573
47589
  * @connect thinking.onSuccess -> acting.execute
47574
47590
  * @connect thinking.action -> acting.action
47575
47591
  * @connect thinking.actionInput -> acting.actionInput
47576
- * @connect thinking.thought -> loop.thought
47577
- * @connect thinking.action -> loop.action
47578
- * @connect thinking.actionInput -> loop.actionInput
47579
- * @connect thinking.onFailure -> loop.failure
47580
- * @connect acting.observation -> loop.observation
47581
- * @connect acting.onSuccess -> loop.success
47582
- * @connect acting.onFailure -> loop.failure
47592
+ * @connect thinking.thought -> loop.thought:step
47593
+ * @connect thinking.action -> loop.action:step
47594
+ * @connect thinking.actionInput -> loop.actionInput:step
47595
+ * @connect thinking.onFailure -> loop.failure:step
47596
+ * @connect acting.observation -> loop.observation:step
47597
+ * @connect acting.onSuccess -> loop.success:step
47598
+ * @connect acting.onFailure -> loop.failure:step
47583
47599
  * @connect loop.onSuccess -> Exit.onSuccess
47584
47600
  * @connect loop.onFailure -> Exit.onFailure
47585
47601
  * @connect loop.answer -> Exit.answer
@@ -47655,7 +47671,7 @@ const documentStore: Document[] = [
47655
47671
  * @flowWeaver nodeType
47656
47672
  * @label Retrieve
47657
47673
  * @input query [order:1] - Search query
47658
- * @input topK [order:2] - Number of results (default 3)
47674
+ * @input [topK] [order:2] - Number of results (default 3)
47659
47675
  * @input execute [order:0] - Execute
47660
47676
  * @output documents [order:2] - Retrieved documents
47661
47677
  * @output context [order:3] - Combined document text
@@ -47754,8 +47770,8 @@ Answer:\`;
47754
47770
  * RAG Pipeline for knowledge-based Q&A
47755
47771
  *
47756
47772
  * @flowWeaver workflow
47757
- * @node retriever retrieve [position: -50 0]
47758
- * @node generator generate [position: 200 0]
47773
+ * @node retriever retrieve [position: -50 0] [color: "teal"] [icon: "search"] [suppress: "UNUSED_OUTPUT_PORT"]
47774
+ * @node generator generate [position: 200 0] [color: "purple"] [icon: "autoAwesome"]
47759
47775
  * @position Start -300 0
47760
47776
  * @position Exit 400 0
47761
47777
  * @connect Start.execute -> retriever.execute
@@ -47836,7 +47852,7 @@ Be concise but friendly. Remember context from earlier in the conversation.\`;
47836
47852
  * @flowWeaver nodeType
47837
47853
  * @label Memory
47838
47854
  * @input conversationId [order:1] - Conversation identifier
47839
- * @input newMessage [order:2] - Message to add
47855
+ * @input [newMessage] [order:2] - Message to add
47840
47856
  * @input [maxHistory=50] [order:3] - Max messages to retain
47841
47857
  * @input execute [order:0] - Execute
47842
47858
  * @output history [order:2] - Conversation history
@@ -47924,9 +47940,9 @@ async function chat(
47924
47940
  * Stateful chat with conversation memory
47925
47941
  *
47926
47942
  * @flowWeaver workflow
47927
- * @node mem memory [position: -150 0]
47928
- * @node respond chat [position: 50 0]
47929
- * @node saveMem memory [position: 250 0]
47943
+ * @node mem memory [position: -150 0] [color: "teal"] [icon: "database"]
47944
+ * @node respond chat [position: 50 0] [color: "purple"] [icon: "campaign"] [suppress: "AGENT_LLM_NO_FALLBACK"]
47945
+ * @node saveMem memory [position: 250 0] [color: "teal"] [icon: "database"] [suppress: "UNUSED_OUTPUT_PORT"]
47930
47946
  * @position Start -350 0
47931
47947
  * @position Exit 450 0
47932
47948
  * @connect Start.execute -> mem.execute
@@ -47937,6 +47953,7 @@ async function chat(
47937
47953
  * @connect Start.conversationId -> saveMem.conversationId
47938
47954
  * @connect respond.responseMessage -> saveMem.newMessage
47939
47955
  * @connect respond.onSuccess -> saveMem.execute
47956
+ * @connect respond.onFailure -> Exit.onFailure
47940
47957
  * @connect respond.response -> Exit.response
47941
47958
  * @connect saveMem.onSuccess -> Exit.onSuccess
47942
47959
  * @param execute [order:0] - Execute
@@ -48032,9 +48049,9 @@ function combineData(dataA: any, dataB: any): { aggregated: any } {
48032
48049
 
48033
48050
  /**
48034
48051
  * @flowWeaver workflow
48035
- * @node sourceA fetchSourceA [position: -180 -90]
48036
- * @node sourceB fetchSourceB [position: -180 90]
48037
- * @node combiner combineData [position: 90 0]
48052
+ * @node sourceA fetchSourceA [position: -180 -90] [color: "blue"] [icon: "download"]
48053
+ * @node sourceB fetchSourceB [position: -180 90] [color: "blue"] [icon: "download"]
48054
+ * @node combiner combineData [position: 90 0] [color: "purple"] [icon: "callMerge"]
48038
48055
  * @position Start -450 0
48039
48056
  * @position Exit 360 0
48040
48057
  * @connect Start.execute -> sourceA.execute
@@ -48186,9 +48203,9 @@ function formatResponse(
48186
48203
 
48187
48204
  /**
48188
48205
  * @flowWeaver workflow
48189
- * @node validator validateRequest [position: -180 0]
48190
- * @node processor processPayload [position: 90 -60]
48191
- * @node responder formatResponse [position: 270 0]
48206
+ * @node validator validateRequest [position: -180 0] [color: "green"] [icon: "verified"]
48207
+ * @node processor processPayload [position: 90 -60] [color: "blue"] [icon: "settings"]
48208
+ * @node responder formatResponse [position: 270 0] [color: "cyan"] [icon: "send"]
48192
48209
  * @position Start -450 0
48193
48210
  * @position Exit 450 0
48194
48211
  * @connect Start.execute -> validator.execute
@@ -48330,8 +48347,8 @@ function tryOperation(
48330
48347
 
48331
48348
  /**
48332
48349
  * @flowWeaver workflow
48333
- * @node loop retryLoop [size: 300 200] [position: -90 0]
48334
- * @node tryOp tryOperation loop.attempt [position: 90 0]
48350
+ * @node loop retryLoop [position: -90 0] [color: "orange"] [icon: "refresh"]
48351
+ * @node tryOp tryOperation loop.attempt [color: "blue"] [icon: "playArrow"]
48335
48352
  * @position Start -450 0
48336
48353
  * @position Exit 360 0
48337
48354
  * @connect Start.execute -> loop.execute
@@ -106693,7 +106710,7 @@ function displayInstalledPackage(pkg) {
106693
106710
  // src/cli/index.ts
106694
106711
  init_logger();
106695
106712
  init_error_utils();
106696
- var version2 = true ? "0.20.2" : "0.0.0-dev";
106713
+ var version2 = true ? "0.20.4" : "0.0.0-dev";
106697
106714
  var program2 = new Command();
106698
106715
  program2.name("flow-weaver").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", () => {
106699
106716
  logger.banner(version2);
@@ -68,9 +68,9 @@ function combineData(dataA: any, dataB: any): { aggregated: any } {
68
68
 
69
69
  /**
70
70
  * @flowWeaver workflow
71
- * @node sourceA fetchSourceA [position: -180 -90]
72
- * @node sourceB fetchSourceB [position: -180 90]
73
- * @node combiner combineData [position: 90 0]
71
+ * @node sourceA fetchSourceA [position: -180 -90] [color: "blue"] [icon: "download"]
72
+ * @node sourceB fetchSourceB [position: -180 90] [color: "blue"] [icon: "download"]
73
+ * @node combiner combineData [position: 90 0] [color: "purple"] [icon: "callMerge"]
74
74
  * @position Start -450 0
75
75
  * @position Exit 360 0
76
76
  * @connect Start.execute -> sourceA.execute
@@ -283,9 +283,9 @@ async function executeTools(
283
283
  * AI Agent that uses tools to accomplish tasks
284
284
  *
285
285
  * @flowWeaver workflow
286
- * @node loop agentLoop [size: 450 350] [position: -180 0]
287
- * @node llm callLLM loop.iteration [position: -40 100]
288
- * @node tools executeTools loop.iteration [position: 120 200]
286
+ * @node loop agentLoop [position: -180 0] [color: "purple"] [icon: "smartToy"]
287
+ * @node llm callLLM loop.iteration [color: "blue"] [icon: "psychology"]
288
+ * @node tools executeTools loop.iteration [color: "orange"] [icon: "build"] [suppress: "AGENT_UNGUARDED_TOOL_EXECUTOR"]
289
289
  * @position Start -450 0
290
290
  * @position Exit 360 0
291
291
  * @connect Start.execute -> loop.execute
@@ -39,7 +39,7 @@ Be concise but friendly. Remember context from earlier in the conversation.\`;
39
39
  * @flowWeaver nodeType
40
40
  * @label Memory
41
41
  * @input conversationId [order:1] - Conversation identifier
42
- * @input newMessage [order:2] - Message to add
42
+ * @input [newMessage] [order:2] - Message to add
43
43
  * @input [maxHistory=50] [order:3] - Max messages to retain
44
44
  * @input execute [order:0] - Execute
45
45
  * @output history [order:2] - Conversation history
@@ -127,9 +127,9 @@ async function chat(
127
127
  * Stateful chat with conversation memory
128
128
  *
129
129
  * @flowWeaver workflow
130
- * @node mem memory [position: -150 0]
131
- * @node respond chat [position: 50 0]
132
- * @node saveMem memory [position: 250 0]
130
+ * @node mem memory [position: -150 0] [color: "teal"] [icon: "database"]
131
+ * @node respond chat [position: 50 0] [color: "purple"] [icon: "campaign"] [suppress: "AGENT_LLM_NO_FALLBACK"]
132
+ * @node saveMem memory [position: 250 0] [color: "teal"] [icon: "database"] [suppress: "UNUSED_OUTPUT_PORT"]
133
133
  * @position Start -350 0
134
134
  * @position Exit 450 0
135
135
  * @connect Start.execute -> mem.execute
@@ -140,6 +140,7 @@ async function chat(
140
140
  * @connect Start.conversationId -> saveMem.conversationId
141
141
  * @connect respond.responseMessage -> saveMem.newMessage
142
142
  * @connect respond.onSuccess -> saveMem.execute
143
+ * @connect respond.onFailure -> Exit.onFailure
143
144
  * @connect respond.response -> Exit.response
144
145
  * @connect saveMem.onSuccess -> Exit.onSuccess
145
146
  * @param execute [order:0] - Execute
@@ -46,7 +46,7 @@ const documentStore: Document[] = [
46
46
  * @flowWeaver nodeType
47
47
  * @label Retrieve
48
48
  * @input query [order:1] - Search query
49
- * @input topK [order:2] - Number of results (default 3)
49
+ * @input [topK] [order:2] - Number of results (default 3)
50
50
  * @input execute [order:0] - Execute
51
51
  * @output documents [order:2] - Retrieved documents
52
52
  * @output context [order:3] - Combined document text
@@ -145,8 +145,8 @@ Answer:\`;
145
145
  * RAG Pipeline for knowledge-based Q&A
146
146
  *
147
147
  * @flowWeaver workflow
148
- * @node retriever retrieve [position: -50 0]
149
- * @node generator generate [position: 200 0]
148
+ * @node retriever retrieve [position: -50 0] [color: "teal"] [icon: "search"] [suppress: "UNUSED_OUTPUT_PORT"]
149
+ * @node generator generate [position: 200 0] [color: "purple"] [icon: "autoAwesome"]
150
150
  * @position Start -300 0
151
151
  * @position Exit 400 0
152
152
  * @connect Start.execute -> retriever.execute
@@ -247,25 +247,25 @@ async function act(
247
247
  * ReAct Agent — iterative Thought→Action→Observation loop
248
248
  *
249
249
  * @flowWeaver workflow
250
- * @node loop reactLoop [size: 450 250] [position: -150 0]
251
- * @node thinking think loop.step [position: -80 30]
252
- * @node acting act loop.step [position: 130 30]
250
+ * @node loop reactLoop [position: -150 0] [color: "purple"] [icon: "psychology"]
251
+ * @node thinking think loop.step [color: "blue"] [icon: "autoAwesome"]
252
+ * @node acting act loop.step [color: "orange"] [icon: "bolt"]
253
253
  * @position Start -400 0
254
254
  * @position Exit 350 0
255
255
  * @connect Start.execute -> loop.execute
256
256
  * @connect Start.task -> loop.task
257
- * @connect loop.start -> thinking.execute
258
- * @connect loop.messages -> thinking.messages
257
+ * @connect loop.start:step -> thinking.execute
258
+ * @connect loop.messages:step -> thinking.messages
259
259
  * @connect thinking.onSuccess -> acting.execute
260
260
  * @connect thinking.action -> acting.action
261
261
  * @connect thinking.actionInput -> acting.actionInput
262
- * @connect thinking.thought -> loop.thought
263
- * @connect thinking.action -> loop.action
264
- * @connect thinking.actionInput -> loop.actionInput
265
- * @connect thinking.onFailure -> loop.failure
266
- * @connect acting.observation -> loop.observation
267
- * @connect acting.onSuccess -> loop.success
268
- * @connect acting.onFailure -> loop.failure
262
+ * @connect thinking.thought -> loop.thought:step
263
+ * @connect thinking.action -> loop.action:step
264
+ * @connect thinking.actionInput -> loop.actionInput:step
265
+ * @connect thinking.onFailure -> loop.failure:step
266
+ * @connect acting.observation -> loop.observation:step
267
+ * @connect acting.onSuccess -> loop.success:step
268
+ * @connect acting.onFailure -> loop.failure:step
269
269
  * @connect loop.onSuccess -> Exit.onSuccess
270
270
  * @connect loop.onFailure -> Exit.onFailure
271
271
  * @connect loop.answer -> Exit.answer
@@ -105,9 +105,9 @@ function handleFailure(
105
105
 
106
106
  /**
107
107
  * @flowWeaver workflow
108
- * @node router evaluateCondition [position: -180 0]
109
- * @node successHandler handleSuccess [position: 90 -90]
110
- * @node failureHandler handleFailure [position: 90 90]
108
+ * @node router evaluateCondition [position: -180 0] [color: "orange"] [icon: "altRoute"] [suppress: "UNUSED_OUTPUT_PORT"]
109
+ * @node successHandler handleSuccess [position: 90 -90] [color: "green"] [icon: "checkCircle"]
110
+ * @node failureHandler handleFailure [position: 90 90] [color: "red"] [icon: "error"]
111
111
  * @position Start -450 0
112
112
  * @position Exit 360 0
113
113
  * @connect Start.execute -> router.execute
@@ -105,8 +105,8 @@ function tryOperation(
105
105
 
106
106
  /**
107
107
  * @flowWeaver workflow
108
- * @node loop retryLoop [size: 300 200] [position: -90 0]
109
- * @node tryOp tryOperation loop.attempt [position: 90 0]
108
+ * @node loop retryLoop [position: -90 0] [color: "orange"] [icon: "refresh"]
109
+ * @node tryOp tryOperation loop.attempt [color: "blue"] [icon: "playArrow"]
110
110
  * @position Start -450 0
111
111
  * @position Exit 360 0
112
112
  * @connect Start.execute -> loop.execute
@@ -101,9 +101,9 @@ function aggregateResults(
101
101
 
102
102
  /**
103
103
  * @flowWeaver workflow
104
- * @node iterator forEachItem [size: 300 200] [position: -90 0]
105
- * @node processor processItem iterator.processItem [position: 90 0]
106
- * @node aggregator aggregateResults [position: 270 0]
104
+ * @node iterator forEachItem [position: -90 0] [color: "purple"] [icon: "repeat"]
105
+ * @node processor processItem iterator.processItem [color: "blue"] [icon: "settings"]
106
+ * @node aggregator aggregateResults [position: 270 0] [color: "teal"] [icon: "inventory"]
107
107
  * @position Start -450 0
108
108
  * @position Exit 450 0
109
109
  * @connect Start.execute -> iterator.execute
@@ -87,12 +87,13 @@ function outputResult(data: any): { result: any } {
87
87
 
88
88
  /**
89
89
  * @flowWeaver workflow
90
- * @node validator validateData [position: -300 0]
91
- * @node transformer transformData [position: 0 0]
92
- * @node outputter outputResult [position: 300 0]
90
+ * @node validator validateData [position: -300 0] [color: "green"] [icon: "verified"] [suppress: "UNUSED_OUTPUT_PORT"]
91
+ * @node transformer transformData [position: 0 0] [color: "blue"] [icon: "sync"]
92
+ * @node outputter outputResult [position: 300 0] [color: "cyan"] [icon: "inventory"]
93
93
  * @position Start -600 0
94
94
  * @position Exit 600 0
95
95
  * @path Start -> validator -> transformer -> outputter -> Exit
96
+ * @connect outputter.result -> Exit.result
96
97
  * @connect validator.onFailure -> Exit.onFailure
97
98
  * @connect validator.error -> Exit.error
98
99
  * @param execute [order:0] - Execute
@@ -134,9 +135,11 @@ function ${name}(${inputPortName}: any): { ${outputPortName}: any } {
134
135
  // Generate workflow annotations
135
136
  const spacing = 300;
136
137
  const startX = -(nodeNames.length * (spacing / 2) + spacing / 2);
138
+ const stepColors = ['green', 'blue', 'cyan', 'orange', 'purple', 'teal', 'pink', 'yellow'];
137
139
  const nodeAnnotations = nodeNames.map((name, i) => {
138
140
  const x = startX + (i + 1) * spacing;
139
- return ` * @node step${i} ${name} [position: ${x} 0]`;
141
+ const color = stepColors[i % stepColors.length];
142
+ return ` * @node step${i} ${name} [position: ${x} 0] [color: "${color}"] [icon: "settings"]`;
140
143
  }).join('\n');
141
144
  const positionAnnotations = [
142
145
  ` * @position Start ${startX} 0`,
@@ -120,9 +120,9 @@ function formatResponse(
120
120
 
121
121
  /**
122
122
  * @flowWeaver workflow
123
- * @node validator validateRequest [position: -180 0]
124
- * @node processor processPayload [position: 90 -60]
125
- * @node responder formatResponse [position: 270 0]
123
+ * @node validator validateRequest [position: -180 0] [color: "green"] [icon: "verified"]
124
+ * @node processor processPayload [position: 90 -60] [color: "blue"] [icon: "settings"]
125
+ * @node responder formatResponse [position: 270 0] [color: "cyan"] [icon: "send"]
126
126
  * @position Start -450 0
127
127
  * @position Exit 450 0
128
128
  * @connect Start.execute -> validator.execute
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.20.2";
1
+ export declare const VERSION = "0.20.4";
2
2
  //# sourceMappingURL=generated-version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by scripts/generate-version.ts — do not edit manually
2
- export const VERSION = '0.20.2';
2
+ export const VERSION = '0.20.4';
3
3
  //# sourceMappingURL=generated-version.js.map
@@ -740,7 +740,7 @@ export class JSDocParser {
740
740
  else if (func) {
741
741
  const returnType = func.getReturnType();
742
742
  const returnTypeText = returnType.getText();
743
- const fieldMatch = returnTypeText.match(new RegExp(`${name}\\s*:\\s*([^;},]+)`));
743
+ const fieldMatch = returnTypeText.match(new RegExp(`${name}\\??\\s*:\\s*([^;},]+)`));
744
744
  if (fieldMatch) {
745
745
  type = inferDataTypeFromTS(fieldMatch[1].trim());
746
746
  }
@@ -795,7 +795,7 @@ export class JSDocParser {
795
795
  paramTypeText === '{}' ||
796
796
  /^\{\s*\[[\w]+:\s*string\]:\s*(never|any|unknown);\s*\}$/.test(paramTypeText));
797
797
  if (!isCatchAllRecord) {
798
- const fieldMatch = paramTypeText.match(new RegExp(`${name}\\s*:\\s*([^;},]+)`));
798
+ const fieldMatch = paramTypeText.match(new RegExp(`${name}\\??\\s*:\\s*([^;},]+)`));
799
799
  if (fieldMatch) {
800
800
  type = inferDataTypeFromTS(fieldMatch[1].trim());
801
801
  }
@@ -538,6 +538,7 @@ flow-weaver modify setLabel --file <path> --nodeId <id> --label <text>
538
538
 
539
539
  Sets the display label for a node instance.
540
540
 
541
+
541
542
  **Examples:**
542
543
  ```bash
543
544
  flow-weaver modify addNode --file workflow.ts --nodeId validator --nodeType validateInput
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synergenius/flow-weaver",
3
- "version": "0.20.2",
3
+ "version": "0.20.4",
4
4
  "description": "Deterministic workflow compiler for AI agents. Compiles to standalone TypeScript, no runtime dependencies.",
5
5
  "private": false,
6
6
  "type": "module",