@synergenius/flow-weaver 0.33.2 → 0.44.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 (922) hide show
  1. package/LICENSE +201 -226
  2. package/NOTICE +13 -0
  3. package/README.md +152 -245
  4. package/dist/agent/agent-loop.d.ts +4 -2
  5. package/dist/agent/cli-session.d.ts +3 -3
  6. package/dist/agent/cli-session.js +511 -438
  7. package/dist/agent/cli-spawn-config.d.ts +4 -4
  8. package/dist/agent/gate.d.ts +164 -0
  9. package/dist/agent/index.d.ts +4 -4
  10. package/dist/agent/index.js +174 -28
  11. package/dist/agent/mcp-bridge.d.ts +1 -1
  12. package/dist/agent/mcp-bridge.js +114 -128
  13. package/dist/agent/mcp-tool-server.d.ts +2 -2
  14. package/dist/agent/mcp-tool-server.js +147 -189
  15. package/dist/agent/profiles.d.ts +69 -0
  16. package/dist/agent/providers/anthropic.d.ts +2 -4
  17. package/dist/agent/providers/claude-cli.d.ts +4 -5
  18. package/dist/agent/providers/openai-compat.d.ts +8 -1
  19. package/dist/agent/streaming.d.ts +2 -2
  20. package/dist/agent/types.d.ts +16 -10
  21. package/dist/api/builder.d.ts +3 -3
  22. package/dist/api/compile.d.ts +9 -4
  23. package/dist/api/durable-validation.d.ts +15 -0
  24. package/dist/api/generate-in-place.d.ts +21 -19
  25. package/dist/api/generate.d.ts +21 -16
  26. package/dist/api/generated-module/local-node-functions.d.ts +24 -0
  27. package/dist/api/generated-module/module-format.d.ts +23 -0
  28. package/dist/api/generated-module/module-writer.d.ts +34 -0
  29. package/dist/api/generated-module/node-type-imports.d.ts +39 -0
  30. package/dist/api/generated-module/preamble.d.ts +16 -0
  31. package/dist/api/generated-module/workflow-functions.d.ts +29 -0
  32. package/dist/api/graph-identity.d.ts +39 -0
  33. package/dist/api/helpers.d.ts +4 -60
  34. package/dist/api/in-place/built-in-nodes.d.ts +18 -0
  35. package/dist/api/in-place/function-body.d.ts +21 -0
  36. package/dist/api/in-place/fw-imports.d.ts +30 -0
  37. package/dist/api/in-place/macro-coverage.d.ts +14 -0
  38. package/dist/api/in-place/node-type-functions.d.ts +18 -0
  39. package/dist/api/in-place/node-type-jsdoc.d.ts +20 -0
  40. package/dist/api/in-place/orphaned-node-types.d.ts +16 -0
  41. package/dist/api/in-place/runtime-section.d.ts +16 -0
  42. package/dist/api/in-place/signature.d.ts +47 -0
  43. package/dist/api/in-place/source-file.d.ts +19 -0
  44. package/dist/api/in-place/workflow-jsdoc.d.ts +19 -0
  45. package/dist/api/index.d.ts +18 -21
  46. package/dist/api/index.js +259 -53
  47. package/dist/api/inline-engine.generated.d.ts +3 -0
  48. package/dist/api/inline-runtime.d.ts +10 -2
  49. package/dist/api/manipulation/connections.d.ts +1 -1
  50. package/dist/api/manipulation/index.d.ts +8 -8
  51. package/dist/api/manipulation/node-types.d.ts +1 -1
  52. package/dist/api/manipulation/nodes.d.ts +3 -13
  53. package/dist/api/manipulation/ports.d.ts +1 -1
  54. package/dist/api/manipulation/scopes.d.ts +1 -1
  55. package/dist/api/manipulation/workflow.d.ts +1 -1
  56. package/dist/api/modify-operation.d.ts +0 -2
  57. package/dist/api/parse.d.ts +22 -1
  58. package/dist/api/port-references.d.ts +66 -0
  59. package/dist/api/query.d.ts +18 -2
  60. package/dist/api/templates.d.ts +1 -1
  61. package/dist/api/transform.d.ts +1 -1
  62. package/dist/api/validate.d.ts +1 -1
  63. package/dist/api/validation-registry.d.ts +2 -2
  64. package/dist/artifacts/brief.d.ts +43 -0
  65. package/dist/artifacts/index.d.ts +31 -0
  66. package/dist/artifacts/pdf.d.ts +19 -0
  67. package/dist/ast/builder.d.ts +3 -3
  68. package/dist/ast/index.d.ts +4 -4
  69. package/dist/ast/index.js +60 -5
  70. package/dist/ast/serialization-node.d.ts +1 -1
  71. package/dist/ast/serialization.d.ts +1 -1
  72. package/dist/ast/types.d.ts +82 -291
  73. package/dist/ast/workflow-utils.d.ts +4 -4
  74. package/dist/built-in-nodes/coercion-types.d.ts +1 -1
  75. package/dist/built-in-nodes/delay.d.ts +3 -1
  76. package/dist/built-in-nodes/generated-registry.d.ts +1 -1
  77. package/dist/built-in-nodes/index.d.ts +6 -5
  78. package/dist/built-in-nodes/index.js +79 -5
  79. package/dist/built-in-nodes/invoke-workflow.d.ts +2 -1
  80. package/dist/built-in-nodes/mock-types.d.ts +45 -14
  81. package/dist/built-in-nodes/sleep.d.ts +12 -0
  82. package/dist/built-in-nodes/wait-for-agent.d.ts +2 -1
  83. package/dist/built-in-nodes/wait-for-event.d.ts +2 -1
  84. package/dist/chevrotain-parser/coerce-parser.d.ts +1 -1
  85. package/dist/chevrotain-parser/connect-parser.d.ts +1 -1
  86. package/dist/chevrotain-parser/grammar-diagrams.d.ts +1 -1
  87. package/dist/chevrotain-parser/index.d.ts +20 -23
  88. package/dist/chevrotain-parser/node-parser.d.ts +7 -8
  89. package/dist/chevrotain-parser/parse-line.d.ts +54 -0
  90. package/dist/chevrotain-parser/tokens.d.ts +0 -17
  91. package/dist/chevrotain-parser/trigger-cancel-parser.d.ts +6 -1
  92. package/dist/chunks/chunk-4EUSHAY6.js +298 -0
  93. package/dist/chunks/chunk-4KDUEOFD.js +197 -0
  94. package/dist/chunks/chunk-5Y3AIUWY.js +911 -0
  95. package/dist/chunks/chunk-6KMVP6AU.js +20 -0
  96. package/dist/chunks/chunk-6PNJORFL.js +128 -0
  97. package/dist/chunks/chunk-7AAQNGRH.js +2001 -0
  98. package/dist/chunks/chunk-7YYKTPJ5.js +22705 -0
  99. package/dist/chunks/chunk-A5MBOFVY.js +33 -0
  100. package/dist/chunks/chunk-AXNQRVJB.js +18 -0
  101. package/dist/chunks/chunk-B6HQ6YS5.js +572 -0
  102. package/dist/chunks/chunk-CY3RNVML.js +296 -0
  103. package/dist/chunks/chunk-CYHYDLV4.js +653 -0
  104. package/dist/chunks/chunk-CZBCCK4Y.js +82 -0
  105. package/dist/chunks/chunk-DCMGQP5V.js +505 -0
  106. package/dist/chunks/chunk-DIAA66GL.js +72 -0
  107. package/dist/chunks/chunk-DUO6H5PR.js +20 -0
  108. package/dist/chunks/chunk-E5WN7IGO.js +125 -0
  109. package/dist/chunks/chunk-EFGFXXQF.js +184 -0
  110. package/dist/chunks/chunk-F3RTZV2A.js +2811 -0
  111. package/dist/chunks/chunk-FMTLP5ZX.js +1397 -0
  112. package/dist/chunks/chunk-HKZLQJDV.js +79 -0
  113. package/dist/chunks/chunk-INDEVYEC.js +146 -0
  114. package/dist/chunks/chunk-JQTF4R5L.js +390 -0
  115. package/dist/chunks/chunk-KMCAYNUM.js +331 -0
  116. package/dist/chunks/chunk-KMWCCOUJ.js +1444 -0
  117. package/dist/chunks/chunk-KU3CLJI2.js +338 -0
  118. package/dist/chunks/chunk-NDSTGMKR.js +3300 -0
  119. package/dist/chunks/chunk-NQNLUAPO.js +505 -0
  120. package/dist/chunks/chunk-O2U2LO57.js +466 -0
  121. package/dist/chunks/chunk-OOQG7UPP.js +457 -0
  122. package/dist/chunks/chunk-OZQAW5ZG.js +112 -0
  123. package/dist/chunks/chunk-P2CVDGHR.js +487 -0
  124. package/dist/chunks/chunk-P44RIZ7C.js +592 -0
  125. package/dist/chunks/chunk-PEZCT37T.js +1475 -0
  126. package/dist/chunks/chunk-PKWSAW6O.js +152 -0
  127. package/dist/chunks/chunk-Q6MDDZMT.js +4373 -0
  128. package/dist/chunks/chunk-QDE4Z7KW.js +6 -0
  129. package/dist/chunks/chunk-QJDAVSNY.js +8 -0
  130. package/dist/chunks/chunk-QYPORSLO.js +7552 -0
  131. package/dist/chunks/chunk-R4QGNK34.js +183 -0
  132. package/dist/chunks/chunk-REEYC73I.js +3002 -0
  133. package/dist/chunks/chunk-SEWDMQ6Q.js +46 -0
  134. package/dist/chunks/chunk-TAIUWKZB.js +3057 -0
  135. package/dist/chunks/chunk-TN4YZ3O7.js +196 -0
  136. package/dist/chunks/chunk-TRMFB43C.js +143 -0
  137. package/dist/chunks/chunk-VO4QXG2X.js +1016 -0
  138. package/dist/chunks/chunk-VP2P3BPA.js +1002 -0
  139. package/dist/chunks/chunk-VQ7H33J4.js +2176 -0
  140. package/dist/chunks/chunk-VWA7MCV2.js +105 -0
  141. package/dist/chunks/chunk-XAV22WD7.js +253 -0
  142. package/dist/chunks/chunk-YSPBPZDV.js +148 -0
  143. package/dist/chunks/chunk-ZKEGXO73.js +282 -0
  144. package/dist/chunks/chunk-ZMGN6F3S.js +4256 -0
  145. package/dist/chunks/grammar-diagrams-AI7VDXOM.js +14 -0
  146. package/dist/chunks/index.min-ECJD6GZC.js +37 -0
  147. package/dist/chunks/manifest-EPTR5MYH.js +21 -0
  148. package/dist/chunks/openapi-document-6TCGVDUW.js +69 -0
  149. package/dist/chunks/registry-K2U5KUTY.js +23 -0
  150. package/dist/chunks/serialization-node-UGY6CFH6.js +38 -0
  151. package/dist/chunks/validate-GEKSZPIN.js +24 -0
  152. package/dist/chunks/validation-registry-IQZX3UE3.js +7 -0
  153. package/dist/chunks/validator-VXFHLPDW.js +26 -0
  154. package/dist/chunks/workflow-executor-KBGFKHNR.js +36 -0
  155. package/dist/cli/commands/agents.d.ts +16 -0
  156. package/dist/cli/commands/artifact.d.ts +10 -0
  157. package/dist/cli/commands/compile.d.ts +0 -30
  158. package/dist/cli/commands/console.d.ts +32 -0
  159. package/dist/cli/commands/context.d.ts +0 -3
  160. package/dist/cli/commands/describe.js +386 -352
  161. package/dist/cli/commands/dev.d.ts +9 -4
  162. package/dist/cli/commands/diagram.d.ts +3 -5
  163. package/dist/cli/commands/doctor.d.ts +27 -4
  164. package/dist/cli/commands/doctor.js +3307 -633
  165. package/dist/cli/commands/export.d.ts +6 -4
  166. package/dist/cli/commands/grammar.d.ts +0 -3
  167. package/dist/cli/commands/implement.d.ts +1 -1
  168. package/dist/cli/commands/init/agent-handoff.d.ts +28 -0
  169. package/dist/cli/commands/init/config.d.ts +3 -0
  170. package/dist/cli/commands/init/files.d.ts +12 -0
  171. package/dist/cli/commands/init/naming.d.ts +13 -0
  172. package/dist/cli/commands/init/output.d.ts +12 -0
  173. package/dist/cli/commands/init/setup.d.ts +21 -0
  174. package/dist/cli/commands/init/types.d.ts +53 -0
  175. package/dist/cli/commands/init-personas.d.ts +9 -1
  176. package/dist/cli/commands/init.d.ts +24 -88
  177. package/dist/cli/commands/market.d.ts +1 -1
  178. package/dist/cli/commands/mcp-setup.d.ts +1 -4
  179. package/dist/cli/commands/modify.d.ts +0 -5
  180. package/dist/cli/commands/openapi.d.ts +9 -11
  181. package/dist/cli/commands/run.d.ts +0 -4
  182. package/dist/cli/commands/serve.d.ts +24 -26
  183. package/dist/cli/commands/status.d.ts +1 -1
  184. package/dist/cli/exports.d.ts +3 -4
  185. package/dist/cli/exports.js +124 -23
  186. package/dist/cli/flow-weaver-agents-H653446S.mjs +81 -0
  187. package/dist/cli/flow-weaver-artifact-WBFYTW76.mjs +58 -0
  188. package/dist/cli/flow-weaver-chunk-265CEK74.mjs +2 -0
  189. package/dist/cli/flow-weaver-chunk-2C7PZCV5.mjs +186 -0
  190. package/dist/cli/flow-weaver-chunk-3BSYCWPL.mjs +3109 -0
  191. package/dist/cli/flow-weaver-chunk-3MKUQP3D.mjs +547 -0
  192. package/dist/cli/flow-weaver-chunk-3ZLMPQTH.mjs +27 -0
  193. package/dist/cli/flow-weaver-chunk-4DVY73ML.mjs +280 -0
  194. package/dist/cli/flow-weaver-chunk-54M4KNEL.mjs +200 -0
  195. package/dist/cli/flow-weaver-chunk-55QMUZIA.mjs +256 -0
  196. package/dist/cli/flow-weaver-chunk-6ZUJ7LMX.mjs +2003 -0
  197. package/dist/cli/flow-weaver-chunk-7ET6N32V.mjs +419 -0
  198. package/dist/cli/flow-weaver-chunk-7G63RR4K.mjs +8880 -0
  199. package/dist/cli/flow-weaver-chunk-A6M5K3W7.mjs +4418 -0
  200. package/dist/cli/flow-weaver-chunk-AA3NATMX.mjs +154 -0
  201. package/dist/cli/flow-weaver-chunk-APX6MQ5A.mjs +5652 -0
  202. package/dist/cli/flow-weaver-chunk-BHCC5FE5.mjs +17 -0
  203. package/dist/cli/flow-weaver-chunk-DM4BBRRU.mjs +35 -0
  204. package/dist/cli/flow-weaver-chunk-DRN7KPWY.mjs +168 -0
  205. package/dist/cli/flow-weaver-chunk-EKWF27G6.mjs +23 -0
  206. package/dist/cli/flow-weaver-chunk-EM5HWQ4R.mjs +338 -0
  207. package/dist/cli/flow-weaver-chunk-FPPPU2DG.mjs +226 -0
  208. package/dist/cli/flow-weaver-chunk-GAQXZHNO.mjs +3005 -0
  209. package/dist/cli/flow-weaver-chunk-GBUNNP33.mjs +1329 -0
  210. package/dist/cli/flow-weaver-chunk-HMAKDE55.mjs +636 -0
  211. package/dist/cli/flow-weaver-chunk-HQ3ZAN44.mjs +367 -0
  212. package/dist/cli/flow-weaver-chunk-I4APCXYN.mjs +21442 -0
  213. package/dist/cli/flow-weaver-chunk-IJJ4JXTL.mjs +2297 -0
  214. package/dist/cli/flow-weaver-chunk-J7EPZW2I.mjs +33 -0
  215. package/dist/cli/flow-weaver-chunk-KOEMJHLG.mjs +83 -0
  216. package/dist/cli/flow-weaver-chunk-M6CBWQKJ.mjs +271 -0
  217. package/dist/cli/flow-weaver-chunk-MHJ4N652.mjs +1580 -0
  218. package/dist/cli/flow-weaver-chunk-MKAFQWLP.mjs +202 -0
  219. package/dist/cli/flow-weaver-chunk-MMV2XGD3.mjs +3291 -0
  220. package/dist/cli/flow-weaver-chunk-MSI2UJES.mjs +125 -0
  221. package/dist/cli/flow-weaver-chunk-N767YRAI.mjs +48 -0
  222. package/dist/cli/flow-weaver-chunk-NQKKWDGF.mjs +56 -0
  223. package/dist/cli/flow-weaver-chunk-NYZDQYFU.mjs +45 -0
  224. package/dist/cli/flow-weaver-chunk-OMVWSNHJ.mjs +14 -0
  225. package/dist/cli/flow-weaver-chunk-PUWZ47H5.mjs +2188 -0
  226. package/dist/cli/flow-weaver-chunk-QOPRVDES.mjs +46 -0
  227. package/dist/cli/flow-weaver-chunk-RIWE7YTR.mjs +216 -0
  228. package/dist/cli/flow-weaver-chunk-S63Q3JIU.mjs +789 -0
  229. package/dist/cli/flow-weaver-chunk-T7X5A23H.mjs +558 -0
  230. package/dist/cli/flow-weaver-chunk-TLV3VZUN.mjs +2 -0
  231. package/dist/cli/flow-weaver-chunk-TS5P3PIN.mjs +194 -0
  232. package/dist/cli/flow-weaver-chunk-U3EO3X4B.mjs +649 -0
  233. package/dist/cli/flow-weaver-chunk-UNFS3NQP.mjs +34 -0
  234. package/dist/cli/flow-weaver-chunk-V6DHWFQG.mjs +2811 -0
  235. package/dist/cli/flow-weaver-chunk-VXWNLYQU.mjs +9 -0
  236. package/dist/cli/flow-weaver-chunk-W3YNK26P.mjs +149 -0
  237. package/dist/cli/flow-weaver-chunk-XG2WKXYZ.mjs +324 -0
  238. package/dist/cli/flow-weaver-chunk-YLSRZWFK.mjs +2219 -0
  239. package/dist/cli/flow-weaver-chunk-YVPURWS6.mjs +40 -0
  240. package/dist/cli/flow-weaver-chunk-Z44JK332.mjs +582 -0
  241. package/dist/cli/flow-weaver-chunk-Z5ZJPNSY.mjs +517 -0
  242. package/dist/cli/flow-weaver-chunk-ZQALO25T.mjs +594 -0
  243. package/dist/cli/flow-weaver-compile-A2CABDSB.mjs +37 -0
  244. package/dist/cli/flow-weaver-console-6EBHDBTN.mjs +71 -0
  245. package/dist/cli/flow-weaver-context-ECLYANFF.mjs +17 -0
  246. package/dist/cli/flow-weaver-context-ZRUMW2KE.mjs +69 -0
  247. package/dist/cli/flow-weaver-create-WIP4EFNP.mjs +124 -0
  248. package/dist/cli/flow-weaver-deployment-WJJRK7NO.mjs +14 -0
  249. package/dist/cli/flow-weaver-describe-XDIFF5LI.mjs +41 -0
  250. package/dist/cli/flow-weaver-dev-LG2NSQAU.mjs +196 -0
  251. package/dist/cli/flow-weaver-diagram-3EVQARQE.mjs +52 -0
  252. package/dist/cli/flow-weaver-diagram-7LR7O4M2.mjs +44 -0
  253. package/dist/cli/flow-weaver-diff-USF7DJLU.mjs +85 -0
  254. package/dist/cli/flow-weaver-docs-QU2ZOXKH.mjs +96 -0
  255. package/dist/cli/flow-weaver-doctor-K447YWHR.mjs +43 -0
  256. package/dist/cli/flow-weaver-export-LAS6N56Y.mjs +140 -0
  257. package/dist/cli/flow-weaver-grammar-RIRUS3Q6.mjs +49 -0
  258. package/dist/cli/flow-weaver-grammar-diagrams-WXRTW5SK.mjs +15 -0
  259. package/dist/cli/flow-weaver-implement-5JG6BCFZ.mjs +114 -0
  260. package/dist/cli/flow-weaver-index.min-OR5SIHXD.mjs +39 -0
  261. package/dist/cli/flow-weaver-init-34YZNPQX.mjs +972 -0
  262. package/dist/cli/flow-weaver-init-personas-NOGZTQQ2.mjs +48 -0
  263. package/dist/cli/flow-weaver-manifest-4JNUSEB3.mjs +18 -0
  264. package/dist/cli/flow-weaver-market-WA4CKHKV.mjs +444 -0
  265. package/dist/cli/flow-weaver-mcp-setup-O26MGXSD.mjs +22 -0
  266. package/dist/cli/flow-weaver-migrate-VFVEUTPH.mjs +119 -0
  267. package/dist/cli/flow-weaver-modify-VM3JP5K6.mjs +97 -0
  268. package/dist/cli/flow-weaver-openapi-IRBWI3HM.mjs +71 -0
  269. package/dist/cli/flow-weaver-openapi-document-7N6YMPG3.mjs +30 -0
  270. package/dist/cli/flow-weaver-pack-commands-OS2QRXAK.mjs +146 -0
  271. package/dist/cli/flow-weaver-registry-5MLFRPPT.mjs +25 -0
  272. package/dist/cli/flow-weaver-run-DSTLSTHR.mjs +555 -0
  273. package/dist/cli/flow-weaver-serialization-node-LE6PCG4M.mjs +50 -0
  274. package/dist/cli/flow-weaver-serve-NVLCLSOW.mjs +192 -0
  275. package/dist/cli/flow-weaver-server-7IERLVXE.mjs +2925 -0
  276. package/dist/cli/flow-weaver-server-KWF4PXYC.mjs +19112 -0
  277. package/dist/cli/flow-weaver-status-75W2S3YB.mjs +138 -0
  278. package/dist/cli/flow-weaver-strip-AZPXUYVA.mjs +79 -0
  279. package/dist/cli/flow-weaver-templates-DSNMB6K7.mjs +72 -0
  280. package/dist/cli/flow-weaver-validate-A4UWDQN6.mjs +19 -0
  281. package/dist/cli/flow-weaver-validate-GRBZ5W4C.mjs +296 -0
  282. package/dist/cli/flow-weaver-validation-registry-BINGUNXX.mjs +9 -0
  283. package/dist/cli/flow-weaver-validator-TY56CI42.mjs +21 -0
  284. package/dist/cli/flow-weaver-watch-OPPERXL6.mjs +114 -0
  285. package/dist/cli/flow-weaver-workflow-executor-6AHYPXAN.mjs +26 -0
  286. package/dist/cli/flow-weaver.mjs +3557 -89384
  287. package/dist/cli/index.d.ts +5 -2
  288. package/dist/cli/pack-commands-needed.d.ts +12 -0
  289. package/dist/cli/program.d.ts +14 -0
  290. package/dist/cli/templates/ai/mock-provider.d.ts +1 -1
  291. package/dist/cli/templates/index.d.ts +1 -8
  292. package/dist/cli/templates/nodes/agent-router.d.ts +1 -1
  293. package/dist/cli/templates/nodes/aggregator.d.ts +1 -1
  294. package/dist/cli/templates/nodes/conversation-memory.d.ts +1 -1
  295. package/dist/cli/templates/nodes/http.d.ts +1 -1
  296. package/dist/cli/templates/nodes/human-approval.d.ts +1 -1
  297. package/dist/cli/templates/nodes/json-extractor.d.ts +1 -1
  298. package/dist/cli/templates/nodes/llm-call.d.ts +1 -1
  299. package/dist/cli/templates/nodes/prompt-template.d.ts +1 -1
  300. package/dist/cli/templates/nodes/rag-retriever.d.ts +1 -1
  301. package/dist/cli/templates/nodes/tool-executor.d.ts +1 -1
  302. package/dist/cli/templates/nodes/transformer.d.ts +1 -1
  303. package/dist/cli/templates/nodes/validator.d.ts +1 -1
  304. package/dist/cli/templates/shared/approval-types.d.ts +1 -1
  305. package/dist/cli/templates/shared/case.d.ts +14 -0
  306. package/dist/cli/templates/shared/llm-types.d.ts +4 -4
  307. package/dist/cli/templates/workflows/aggregator.d.ts +1 -1
  308. package/dist/cli/templates/workflows/ai-agent.d.ts +1 -1
  309. package/dist/cli/templates/workflows/ai-chat.d.ts +1 -1
  310. package/dist/cli/templates/workflows/ai-rag.d.ts +1 -1
  311. package/dist/cli/templates/workflows/ai-react.d.ts +1 -1
  312. package/dist/cli/templates/workflows/approval.d.ts +10 -0
  313. package/dist/cli/templates/workflows/conditional.d.ts +2 -2
  314. package/dist/cli/templates/workflows/error-handler.d.ts +2 -2
  315. package/dist/cli/templates/workflows/foreach.d.ts +1 -1
  316. package/dist/cli/templates/workflows/sequential.d.ts +1 -1
  317. package/dist/cli/templates/workflows/webhook.d.ts +1 -1
  318. package/dist/cli/utils/interactive.d.ts +6 -0
  319. package/dist/cli/utils/json-option.d.ts +8 -0
  320. package/dist/cli/utils/logger.d.ts +2 -0
  321. package/dist/compiler/durable-source-proof.d.ts +23 -0
  322. package/dist/compiler/executable-artifact.d.ts +29 -0
  323. package/dist/compiler/index.d.ts +4 -0
  324. package/dist/compiler/index.js +36 -0
  325. package/dist/console/app.js +106 -0
  326. package/dist/console/assets/synergenius.svg +18 -0
  327. package/dist/console/author.d.ts +32 -0
  328. package/dist/console/cli-catalog.d.ts +21 -0
  329. package/dist/console/cli-run.d.ts +35 -0
  330. package/dist/console/cli-run.js +46 -0
  331. package/dist/console/debug.d.ts +67 -0
  332. package/dist/console/diff-view.d.ts +96 -0
  333. package/dist/console/export.d.ts +36 -0
  334. package/dist/console/git.d.ts +27 -0
  335. package/dist/console/index.d.ts +4 -0
  336. package/dist/console/index.html +16 -0
  337. package/dist/console/index.js +203 -0
  338. package/dist/console/packs.d.ts +100 -0
  339. package/dist/console/request-guard.d.ts +10 -0
  340. package/dist/console/respond.d.ts +16 -0
  341. package/dist/console/router.d.ts +64 -0
  342. package/dist/console/routes-agents.d.ts +14 -0
  343. package/dist/console/routes-project.d.ts +3 -0
  344. package/dist/console/routes-runs.d.ts +3 -0
  345. package/dist/console/routes-services.d.ts +7 -0
  346. package/dist/console/routes-tools.d.ts +3 -0
  347. package/dist/console/runs.d.ts +69 -0
  348. package/dist/console/scan.d.ts +49 -0
  349. package/dist/console/schema.d.ts +74 -0
  350. package/dist/console/server.d.ts +34 -0
  351. package/dist/console/server.js +43264 -0
  352. package/dist/console/services.d.ts +119 -0
  353. package/dist/console/source.d.ts +23 -0
  354. package/dist/console/status.d.ts +68 -0
  355. package/dist/console/styles.css +1023 -0
  356. package/dist/console/terminals.d.ts +22 -0
  357. package/dist/console/workflow-view.d.ts +153 -0
  358. package/dist/constants.d.ts +5 -1
  359. package/dist/constants.js +56 -167
  360. package/dist/context/index.d.ts +10 -0
  361. package/dist/context/index.js +14 -191
  362. package/dist/coordinator/agent-gate.d.ts +107 -0
  363. package/dist/coordinator/bundle-digest.d.ts +20 -0
  364. package/dist/coordinator/clock-tick.d.ts +4 -0
  365. package/dist/coordinator/effect-receipts.d.ts +10 -0
  366. package/dist/coordinator/errors.d.ts +31 -0
  367. package/dist/coordinator/file-store.d.ts +3 -0
  368. package/dist/coordinator/gate-labeling.d.ts +33 -0
  369. package/dist/coordinator/gate-resolution.d.ts +28 -0
  370. package/dist/coordinator/index.d.ts +12 -0
  371. package/dist/coordinator/index.js +107 -0
  372. package/dist/coordinator/memory-store.d.ts +3 -0
  373. package/dist/coordinator/params.d.ts +18 -0
  374. package/dist/coordinator/run-annotations.d.ts +6 -0
  375. package/dist/coordinator/run-context.d.ts +11 -0
  376. package/dist/coordinator/run-ending.d.ts +5 -0
  377. package/dist/coordinator/run-outcome.d.ts +31 -0
  378. package/dist/coordinator/run-resume.d.ts +6 -0
  379. package/dist/coordinator/run-start.d.ts +4 -0
  380. package/dist/coordinator/run-store.d.ts +275 -0
  381. package/dist/coordinator/run-trace.d.ts +41 -0
  382. package/dist/coordinator/run-views.d.ts +12 -0
  383. package/dist/coordinator/runs-dir.d.ts +26 -0
  384. package/dist/coordinator/store.d.ts +67 -0
  385. package/dist/coordinator/time.d.ts +39 -0
  386. package/dist/coordinator/workflow-selection.d.ts +6 -0
  387. package/dist/deployment/index.d.ts +11 -16
  388. package/dist/deployment/index.js +541 -50
  389. package/dist/deployment/targets/base.d.ts +11 -13
  390. package/dist/deployment/targets/openapi-parts.d.ts +92 -0
  391. package/dist/diagram/arms.d.ts +70 -0
  392. package/dist/diagram/ascii-renderer.d.ts +1 -1
  393. package/dist/diagram/geometry.d.ts +20 -32
  394. package/dist/diagram/graph/bounds.d.ts +30 -0
  395. package/dist/diagram/graph/metrics.d.ts +21 -0
  396. package/dist/diagram/graph/nodes.d.ts +33 -0
  397. package/dist/diagram/graph/placement.d.ts +22 -0
  398. package/dist/diagram/graph/ports.d.ts +23 -0
  399. package/dist/diagram/graph/routing.d.ts +40 -0
  400. package/dist/diagram/graph/scopes.d.ts +30 -0
  401. package/dist/diagram/index.d.ts +15 -23
  402. package/dist/diagram/index.js +632 -111
  403. package/dist/diagram/labels.d.ts +12 -0
  404. package/dist/diagram/lanes.d.ts +93 -0
  405. package/dist/diagram/layout.d.ts +1 -1
  406. package/dist/diagram/material-symbols.d.ts +7 -0
  407. package/dist/diagram/orthogonal-router.d.ts +2 -3
  408. package/dist/diagram/process-view.d.ts +79 -0
  409. package/dist/diagram/spine.d.ts +25 -0
  410. package/dist/diagram/theme.d.ts +1 -5
  411. package/dist/diagram/types.d.ts +6 -20
  412. package/dist/diff/index.js +53 -9
  413. package/dist/diff/types.d.ts +1 -5
  414. package/dist/doc-metadata/extractors/annotations.d.ts +0 -4
  415. package/dist/doc-metadata/extractors/cli-commands.d.ts +2 -1
  416. package/dist/doc-metadata/extractors/core-metadata.d.ts +19 -4
  417. package/dist/doc-metadata/extractors/error-codes.d.ts +1 -1
  418. package/dist/doc-metadata/extractors/mcp-tools.d.ts +7 -3
  419. package/dist/doc-metadata/index.d.ts +1 -2
  420. package/dist/doc-metadata/index.js +2368 -9
  421. package/dist/doc-metadata/types.d.ts +7 -24
  422. package/dist/docs/guide.d.ts +33 -0
  423. package/dist/docs/index.d.ts +7 -4
  424. package/dist/docs/index.js +298 -298
  425. package/dist/docs/pack-topics.d.ts +18 -0
  426. package/dist/editor-completions/annotationValues.d.ts +1 -1
  427. package/dist/editor-completions/contextParser.d.ts +3 -2
  428. package/dist/editor-completions/dataTypes.d.ts +1 -1
  429. package/dist/editor-completions/goToDefinition.d.ts +1 -1
  430. package/dist/editor-completions/index.d.ts +8 -8
  431. package/dist/editor-completions/index.js +1244 -175
  432. package/dist/editor-completions/jsDocAnnotations.d.ts +1 -1
  433. package/dist/editor-completions/modifierCompletions.d.ts +1 -1
  434. package/dist/export/index.d.ts +7 -1
  435. package/dist/generated-branding.js +8 -21
  436. package/dist/generated-version.d.ts +1 -1
  437. package/dist/generated-version.js +7 -3
  438. package/dist/generator/annotation-generator.d.ts +84 -0
  439. package/dist/generator/async-detection.d.ts +1 -1
  440. package/dist/{body-generator.d.ts → generator/body-generator.d.ts} +7 -3
  441. package/dist/generator/code-utils.d.ts +15 -60
  442. package/dist/generator/connection-reads.d.ts +94 -0
  443. package/dist/generator/control-flow-plan.d.ts +74 -0
  444. package/dist/generator/control-flow.d.ts +1 -1
  445. package/dist/generator/exit-assembly.d.ts +11 -0
  446. package/dist/generator/index.d.ts +4 -5
  447. package/dist/generator/index.js +34 -11
  448. package/dist/generator/input-port-values.d.ts +22 -0
  449. package/dist/generator/{scope-function-generator.d.ts → node-arguments.d.ts} +76 -1
  450. package/dist/generator/node-invocation.d.ts +74 -0
  451. package/dist/{node-types-generator.d.ts → generator/node-types-generator.d.ts} +3 -2
  452. package/dist/generator/scope-closure.d.ts +23 -0
  453. package/dist/generator/scoped-child.d.ts +49 -0
  454. package/dist/{sugar-optimizer.d.ts → generator/sugar-optimizer.d.ts} +1 -1
  455. package/dist/generator/unified.d.ts +14 -2
  456. package/dist/generator/workflow-generator.d.ts +37 -0
  457. package/dist/index.d.ts +29 -26
  458. package/dist/index.js +1322 -92
  459. package/dist/jsdoc-port-sync/apply-diff.d.ts +15 -0
  460. package/dist/jsdoc-port-sync/callback-signature.d.ts +17 -0
  461. package/dist/jsdoc-port-sync/diff.d.ts +5 -7
  462. package/dist/jsdoc-port-sync/incomplete-lines.d.ts +41 -0
  463. package/dist/jsdoc-port-sync/index.d.ts +11 -11
  464. package/dist/jsdoc-port-sync/index.js +88 -45
  465. package/dist/jsdoc-port-sync/jsdoc-to-signature.d.ts +66 -0
  466. package/dist/jsdoc-port-sync/port-parser.d.ts +6 -24
  467. package/dist/jsdoc-port-sync/port-tag-placement.d.ts +55 -0
  468. package/dist/jsdoc-port-sync/scoped-ports.d.ts +21 -0
  469. package/dist/jsdoc-port-sync/signature-parser.d.ts +8 -1
  470. package/dist/jsdoc-port-sync/signature-to-jsdoc.d.ts +77 -0
  471. package/dist/jsdoc-port-sync/sync.d.ts +4 -1
  472. package/dist/marketplace/index.d.ts +5 -3
  473. package/dist/marketplace/index.js +62 -10
  474. package/dist/marketplace/install.d.ts +24 -0
  475. package/dist/marketplace/manifest.d.ts +1 -1
  476. package/dist/marketplace/npmrc.d.ts +24 -0
  477. package/dist/marketplace/registry.d.ts +46 -11
  478. package/dist/marketplace/types.d.ts +41 -24
  479. package/dist/marketplace/validator.d.ts +1 -1
  480. package/dist/mcp/debug-session.d.ts +2 -4
  481. package/dist/mcp/dist-imports.d.ts +12 -0
  482. package/dist/mcp/response-utils.d.ts +11 -9
  483. package/dist/mcp/server.d.ts +0 -1
  484. package/dist/mcp/tools-context.d.ts +11 -0
  485. package/dist/mcp/tools-diagram.d.ts +1 -2
  486. package/dist/mcp/tools-export.d.ts +2 -2
  487. package/dist/mcp/tools-marketplace.d.ts +1 -1
  488. package/dist/mcp/tools-run.d.ts +17 -0
  489. package/dist/mcp/tools-workflow.d.ts +3 -0
  490. package/dist/mcp/types.d.ts +4 -14
  491. package/dist/mcp/workflow-executor.d.ts +57 -19
  492. package/dist/npm-packages.d.ts +1 -1
  493. package/dist/npm-packages.js +10 -473
  494. package/dist/parser/annotation-parser.d.ts +88 -0
  495. package/dist/parser/annotation-suggestion.d.ts +23 -0
  496. package/dist/parser/durable-effect-contract.d.ts +10 -0
  497. package/dist/parser/expression-references.d.ts +101 -0
  498. package/dist/parser/external-node-types.d.ts +69 -0
  499. package/dist/{function-like.d.ts → parser/function-like.d.ts} +10 -3
  500. package/dist/parser/generated-sections.d.ts +25 -0
  501. package/dist/parser/import-resolution.d.ts +67 -0
  502. package/dist/parser/import-stub.d.ts +29 -0
  503. package/dist/parser/jsdoc/config-types.d.ts +209 -0
  504. package/dist/parser/jsdoc/graph-tags.d.ts +54 -0
  505. package/dist/parser/jsdoc/node-type-block.d.ts +23 -0
  506. package/dist/parser/jsdoc/parse-line-once.d.ts +11 -0
  507. package/dist/parser/jsdoc/port-tags.d.ts +42 -0
  508. package/dist/parser/jsdoc/runtime-tags.d.ts +65 -0
  509. package/dist/parser/jsdoc/signature-types.d.ts +52 -0
  510. package/dist/parser/jsdoc/workflow-block.d.ts +22 -0
  511. package/dist/parser/jsdoc-parser.d.ts +23 -0
  512. package/dist/parser/macro-expansion.d.ts +80 -0
  513. package/dist/parser/module-resolution.d.ts +38 -0
  514. package/dist/parser/node-inference.d.ts +39 -0
  515. package/dist/parser/npm-node-types.d.ts +24 -0
  516. package/dist/parser/pack-handlers.d.ts +12 -0
  517. package/dist/parser/path-data-resolution.d.ts +75 -0
  518. package/dist/parser/port-inference.d.ts +15 -0
  519. package/dist/{resolve-package-types.d.ts → parser/resolve-package-types.d.ts} +4 -0
  520. package/dist/parser/serialize-deploy-annotations.d.ts +19 -0
  521. package/dist/parser/tag-registry.d.ts +22 -0
  522. package/dist/parser/workflow-extraction.d.ts +39 -0
  523. package/dist/runtime/ExecutionContext.d.ts +87 -99
  524. package/dist/runtime/continuation-core.d.ts +147 -0
  525. package/dist/runtime/continuation.d.ts +48 -0
  526. package/dist/runtime/debug-controller.d.ts +7 -22
  527. package/dist/runtime/durable-execution.d.ts +176 -0
  528. package/dist/runtime/events.d.ts +16 -1
  529. package/dist/runtime/executable-module-contract.d.ts +16 -0
  530. package/dist/runtime/index.d.ts +13 -10
  531. package/dist/runtime/index.js +947 -9
  532. package/dist/runtime/strict-json.d.ts +15 -0
  533. package/dist/server/access.d.ts +12 -0
  534. package/dist/server/api.d.ts +126 -0
  535. package/dist/server/callback-delivery.d.ts +62 -0
  536. package/dist/server/callback-url.d.ts +44 -0
  537. package/dist/server/context.d.ts +35 -0
  538. package/dist/server/http-error.d.ts +10 -0
  539. package/dist/server/index.d.ts +7 -1
  540. package/dist/server/index.js +125 -6
  541. package/dist/server/openapi-document.d.ts +33 -0
  542. package/dist/server/openapi.d.ts +32 -0
  543. package/dist/server/respond.d.ts +35 -0
  544. package/dist/server/route-params.d.ts +17 -0
  545. package/dist/server/route-plan.d.ts +41 -0
  546. package/dist/server/routes-catalog.d.ts +5 -0
  547. package/dist/server/routes-declared.d.ts +12 -0
  548. package/dist/server/routes-runs.d.ts +8 -0
  549. package/dist/server/run-driver.d.ts +58 -0
  550. package/dist/server/run-view.d.ts +26 -0
  551. package/dist/server/transport.d.ts +35 -0
  552. package/dist/server/types.d.ts +143 -52
  553. package/dist/server/webhook-server.d.ts +12 -38
  554. package/dist/server/workflow-registry.d.ts +7 -4
  555. package/dist/service-registry.d.ts +49 -0
  556. package/dist/service-registry.js +123 -0
  557. package/dist/testing/assertions.d.ts +2 -2
  558. package/dist/testing/index.d.ts +14 -13
  559. package/dist/testing/index.js +582 -24
  560. package/dist/testing/mock-approval.d.ts +3 -5
  561. package/dist/testing/mock-llm.d.ts +2 -3
  562. package/dist/testing/recorder.d.ts +5 -6
  563. package/dist/testing/replayer.d.ts +6 -7
  564. package/dist/testing/run-store-check.d.ts +3 -0
  565. package/dist/testing/token-tracker.d.ts +2 -2
  566. package/dist/{type-mappings.d.ts → types/type-mappings.d.ts} +13 -1
  567. package/dist/utils/error-utils.d.ts +4 -2
  568. package/dist/utils/port-ordering.d.ts +2 -2
  569. package/dist/utils/port-tag-utils.d.ts +1 -1
  570. package/dist/validation/agent-detection.d.ts +17 -5
  571. package/dist/validation/agent-rules.d.ts +6 -7
  572. package/dist/validation/core-rules.d.ts +49 -0
  573. package/dist/validation/design-rules.d.ts +9 -3
  574. package/dist/validation/rule-registry.d.ts +3 -3
  575. package/dist/validation/rules/connections.d.ts +27 -0
  576. package/dist/validation/rules/context.d.ts +11 -0
  577. package/dist/validation/rules/cycles.d.ts +17 -0
  578. package/dist/validation/rules/data-flow.d.ts +19 -0
  579. package/dist/validation/rules/scope-topology.d.ts +35 -0
  580. package/dist/validation/rules/type-compatibility.d.ts +30 -0
  581. package/dist/validation/type-checker.d.ts +39 -0
  582. package/dist/validation/validator-helpers.d.ts +31 -0
  583. package/dist/validation/validator.d.ts +30 -0
  584. package/docs/reference/advanced-annotations.md +277 -60
  585. package/docs/reference/built-in-nodes.md +164 -94
  586. package/docs/reference/cancellation.md +44 -0
  587. package/docs/reference/cli-reference.md +252 -234
  588. package/docs/reference/compilation.md +36 -109
  589. package/docs/reference/concepts.md +80 -63
  590. package/docs/reference/console.md +169 -0
  591. package/docs/reference/debugging.md +26 -57
  592. package/docs/reference/deployment.md +217 -143
  593. package/docs/reference/durable-gates.md +445 -0
  594. package/docs/reference/error-codes.md +90 -43
  595. package/docs/reference/export-interface.md +91 -26
  596. package/docs/reference/iterative-development.md +50 -28
  597. package/docs/reference/jsdoc-grammar.md +66 -311
  598. package/docs/reference/library.md +250 -0
  599. package/docs/reference/marketplace.md +301 -152
  600. package/docs/reference/mcp-tools.md +102 -0
  601. package/docs/reference/node-conversion.md +84 -59
  602. package/docs/reference/orientation.md +68 -0
  603. package/docs/reference/scaffold.md +5 -4
  604. package/docs/reference/tutorial.md +106 -166
  605. package/docs/reference/visual-reference.md +1 -1
  606. package/package.json +85 -50
  607. package/dist/agent/agent-loop.js +0 -156
  608. package/dist/agent/cli-spawn-config.js +0 -65
  609. package/dist/agent/device-connection.d.ts +0 -79
  610. package/dist/agent/device-connection.js +0 -184
  611. package/dist/agent/env-allowlist.js +0 -60
  612. package/dist/agent/providers/anthropic.js +0 -198
  613. package/dist/agent/providers/claude-cli.js +0 -161
  614. package/dist/agent/providers/openai-compat.js +0 -205
  615. package/dist/agent/providers/platform.d.ts +0 -23
  616. package/dist/agent/providers/platform.js +0 -132
  617. package/dist/agent/streaming.js +0 -186
  618. package/dist/agent/types.js +0 -20
  619. package/dist/annotation-generator.d.ts +0 -50
  620. package/dist/annotation-generator.js +0 -743
  621. package/dist/api/builder.js +0 -345
  622. package/dist/api/command-runner.js +0 -787
  623. package/dist/api/compile.js +0 -148
  624. package/dist/api/extract-types.js +0 -57
  625. package/dist/api/generate-in-place.js +0 -1477
  626. package/dist/api/generate.js +0 -514
  627. package/dist/api/helpers.js +0 -285
  628. package/dist/api/inline-runtime.js +0 -526
  629. package/dist/api/manipulation/connections.js +0 -151
  630. package/dist/api/manipulation/index.js +0 -41
  631. package/dist/api/manipulation/node-types.js +0 -200
  632. package/dist/api/manipulation/nodes.js +0 -355
  633. package/dist/api/manipulation/ports.js +0 -228
  634. package/dist/api/manipulation/scopes.js +0 -156
  635. package/dist/api/manipulation/workflow.js +0 -116
  636. package/dist/api/modify-operation.js +0 -177
  637. package/dist/api/parse.js +0 -115
  638. package/dist/api/patterns.d.ts +0 -112
  639. package/dist/api/patterns.js +0 -303
  640. package/dist/api/query.js +0 -840
  641. package/dist/api/templates.js +0 -117
  642. package/dist/api/transform.js +0 -40
  643. package/dist/api/validate.js +0 -64
  644. package/dist/api/validation-registry.js +0 -10
  645. package/dist/api/workflow-file-operations.js +0 -180
  646. package/dist/ast/builder.js +0 -395
  647. package/dist/ast/serialization-node.js +0 -30
  648. package/dist/ast/serialization.js +0 -134
  649. package/dist/ast/types.js +0 -2
  650. package/dist/ast/workflow-utils.js +0 -114
  651. package/dist/body-generator.js +0 -35
  652. package/dist/built-in-nodes/coercion-types.js +0 -61
  653. package/dist/built-in-nodes/delay.js +0 -29
  654. package/dist/built-in-nodes/generated-registry.js +0 -299
  655. package/dist/built-in-nodes/invoke-workflow.js +0 -36
  656. package/dist/built-in-nodes/mock-types.js +0 -42
  657. package/dist/built-in-nodes/wait-for-agent.js +0 -31
  658. package/dist/built-in-nodes/wait-for-event.js +0 -25
  659. package/dist/chevrotain-parser/coerce-parser.js +0 -103
  660. package/dist/chevrotain-parser/connect-parser.js +0 -136
  661. package/dist/chevrotain-parser/fan-parser.js +0 -149
  662. package/dist/chevrotain-parser/grammar-diagrams.js +0 -273
  663. package/dist/chevrotain-parser/index.js +0 -31
  664. package/dist/chevrotain-parser/map-parser.js +0 -130
  665. package/dist/chevrotain-parser/node-parser.js +0 -558
  666. package/dist/chevrotain-parser/path-parser.js +0 -140
  667. package/dist/chevrotain-parser/port-parser.js +0 -519
  668. package/dist/chevrotain-parser/position-parser.d.ts +0 -20
  669. package/dist/chevrotain-parser/position-parser.js +0 -83
  670. package/dist/chevrotain-parser/scope-parser.js +0 -104
  671. package/dist/chevrotain-parser/tokens.js +0 -429
  672. package/dist/chevrotain-parser/trigger-cancel-parser.js +0 -291
  673. package/dist/cli/commands/account.d.ts +0 -4
  674. package/dist/cli/commands/account.js +0 -50
  675. package/dist/cli/commands/ai-credentials.d.ts +0 -12
  676. package/dist/cli/commands/ai-credentials.js +0 -95
  677. package/dist/cli/commands/apikey.d.ts +0 -4
  678. package/dist/cli/commands/apikey.js +0 -64
  679. package/dist/cli/commands/auth.d.ts +0 -9
  680. package/dist/cli/commands/auth.js +0 -255
  681. package/dist/cli/commands/compile.js +0 -331
  682. package/dist/cli/commands/connect.d.ts +0 -4
  683. package/dist/cli/commands/connect.js +0 -163
  684. package/dist/cli/commands/context.js +0 -51
  685. package/dist/cli/commands/create.js +0 -139
  686. package/dist/cli/commands/deploy.d.ts +0 -6
  687. package/dist/cli/commands/deploy.js +0 -74
  688. package/dist/cli/commands/dev.js +0 -227
  689. package/dist/cli/commands/diagram.js +0 -39
  690. package/dist/cli/commands/diff.js +0 -57
  691. package/dist/cli/commands/docs.js +0 -74
  692. package/dist/cli/commands/export.js +0 -153
  693. package/dist/cli/commands/grammar.js +0 -40
  694. package/dist/cli/commands/implement.js +0 -91
  695. package/dist/cli/commands/init-personas.js +0 -541
  696. package/dist/cli/commands/init.js +0 -797
  697. package/dist/cli/commands/market.js +0 -440
  698. package/dist/cli/commands/mcp-setup.js +0 -433
  699. package/dist/cli/commands/migrate.js +0 -91
  700. package/dist/cli/commands/modify.js +0 -58
  701. package/dist/cli/commands/openapi.js +0 -71
  702. package/dist/cli/commands/org.d.ts +0 -8
  703. package/dist/cli/commands/org.js +0 -136
  704. package/dist/cli/commands/pattern.d.ts +0 -34
  705. package/dist/cli/commands/pattern.js +0 -186
  706. package/dist/cli/commands/plugin.d.ts +0 -16
  707. package/dist/cli/commands/plugin.js +0 -176
  708. package/dist/cli/commands/run.js +0 -742
  709. package/dist/cli/commands/serve.js +0 -93
  710. package/dist/cli/commands/status.js +0 -123
  711. package/dist/cli/commands/strip.js +0 -61
  712. package/dist/cli/commands/templates.js +0 -58
  713. package/dist/cli/commands/validate.js +0 -267
  714. package/dist/cli/commands/watch.js +0 -71
  715. package/dist/cli/config/credentials.d.ts +0 -15
  716. package/dist/cli/config/credentials.js +0 -43
  717. package/dist/cli/config/platform-client.d.ts +0 -123
  718. package/dist/cli/config/platform-client.js +0 -248
  719. package/dist/cli/env-setup.js +0 -12
  720. package/dist/cli/index.js +0 -850
  721. package/dist/cli/pack-commands.js +0 -122
  722. package/dist/cli/postinstall.d.ts +0 -16
  723. package/dist/cli/postinstall.js +0 -119
  724. package/dist/cli/templates/ai/mock-provider.js +0 -64
  725. package/dist/cli/templates/ai/types.js +0 -5
  726. package/dist/cli/templates/approvals/index.d.ts +0 -15
  727. package/dist/cli/templates/approvals/index.js +0 -241
  728. package/dist/cli/templates/index.js +0 -123
  729. package/dist/cli/templates/nodes/agent-router.js +0 -114
  730. package/dist/cli/templates/nodes/aggregator.js +0 -63
  731. package/dist/cli/templates/nodes/conversation-memory.js +0 -85
  732. package/dist/cli/templates/nodes/http.js +0 -80
  733. package/dist/cli/templates/nodes/human-approval.js +0 -109
  734. package/dist/cli/templates/nodes/json-extractor.js +0 -119
  735. package/dist/cli/templates/nodes/llm-call.js +0 -106
  736. package/dist/cli/templates/nodes/prompt-template.js +0 -52
  737. package/dist/cli/templates/nodes/rag-retriever.js +0 -128
  738. package/dist/cli/templates/nodes/tool-executor.js +0 -108
  739. package/dist/cli/templates/nodes/transformer.js +0 -68
  740. package/dist/cli/templates/nodes/validator.js +0 -62
  741. package/dist/cli/templates/pack-loader.js +0 -58
  742. package/dist/cli/templates/providers/index.js +0 -239
  743. package/dist/cli/templates/shared/approval-types.js +0 -31
  744. package/dist/cli/templates/shared/llm-types.js +0 -109
  745. package/dist/cli/templates/workflows/aggregator.js +0 -101
  746. package/dist/cli/templates/workflows/ai-agent.js +0 -326
  747. package/dist/cli/templates/workflows/ai-chat.js +0 -167
  748. package/dist/cli/templates/workflows/ai-rag.js +0 -184
  749. package/dist/cli/templates/workflows/ai-react.js +0 -293
  750. package/dist/cli/templates/workflows/conditional.js +0 -139
  751. package/dist/cli/templates/workflows/error-handler.js +0 -145
  752. package/dist/cli/templates/workflows/foreach.js +0 -140
  753. package/dist/cli/templates/workflows/sequential.js +0 -200
  754. package/dist/cli/templates/workflows/webhook.js +0 -158
  755. package/dist/cli/utils/cli-helpers.d.ts +0 -44
  756. package/dist/cli/utils/cli-helpers.js +0 -99
  757. package/dist/cli/utils/logger.js +0 -126
  758. package/dist/cli/utils/parse-int-strict.js +0 -17
  759. package/dist/cli/utils/safe-write.js +0 -54
  760. package/dist/deployment/config/defaults.d.ts +0 -29
  761. package/dist/deployment/config/defaults.js +0 -98
  762. package/dist/deployment/config/loader.d.ts +0 -24
  763. package/dist/deployment/config/loader.js +0 -237
  764. package/dist/deployment/config/types.d.ts +0 -117
  765. package/dist/deployment/config/types.js +0 -5
  766. package/dist/deployment/core/adapters.d.ts +0 -66
  767. package/dist/deployment/core/adapters.js +0 -156
  768. package/dist/deployment/core/executor.d.ts +0 -62
  769. package/dist/deployment/core/executor.js +0 -197
  770. package/dist/deployment/core/formatters.d.ts +0 -42
  771. package/dist/deployment/core/formatters.js +0 -146
  772. package/dist/deployment/openapi/generator.d.ts +0 -146
  773. package/dist/deployment/openapi/generator.js +0 -347
  774. package/dist/deployment/openapi/schema-converter.d.ts +0 -49
  775. package/dist/deployment/openapi/schema-converter.js +0 -192
  776. package/dist/deployment/targets/base.js +0 -855
  777. package/dist/deployment/types.d.ts +0 -140
  778. package/dist/deployment/types.js +0 -8
  779. package/dist/diagram/ascii-renderer.js +0 -528
  780. package/dist/diagram/geometry.js +0 -1226
  781. package/dist/diagram/html-viewer.d.ts +0 -21
  782. package/dist/diagram/html-viewer.js +0 -1745
  783. package/dist/diagram/layout.js +0 -143
  784. package/dist/diagram/orthogonal-router.js +0 -458
  785. package/dist/diagram/renderer.d.ts +0 -3
  786. package/dist/diagram/renderer.js +0 -280
  787. package/dist/diagram/theme.js +0 -282
  788. package/dist/diagram/types.js +0 -2
  789. package/dist/diff/WorkflowDiffer.js +0 -429
  790. package/dist/diff/formatDiff.js +0 -239
  791. package/dist/diff/impact.js +0 -119
  792. package/dist/diff/types.js +0 -35
  793. package/dist/doc-metadata/extractors/annotations.js +0 -638
  794. package/dist/doc-metadata/extractors/cli-commands.js +0 -326
  795. package/dist/doc-metadata/extractors/core-metadata.js +0 -61
  796. package/dist/doc-metadata/extractors/error-codes.js +0 -372
  797. package/dist/doc-metadata/extractors/grammar-rules.js +0 -51
  798. package/dist/doc-metadata/extractors/mcp-tools.js +0 -705
  799. package/dist/doc-metadata/extractors/plugin-api.d.ts +0 -19
  800. package/dist/doc-metadata/extractors/plugin-api.js +0 -279
  801. package/dist/doc-metadata/types.js +0 -5
  802. package/dist/editor-completions/annotationValues.js +0 -146
  803. package/dist/editor-completions/contextParser.js +0 -410
  804. package/dist/editor-completions/dataTypes.js +0 -95
  805. package/dist/editor-completions/goToDefinition.js +0 -112
  806. package/dist/editor-completions/jsDocAnnotations.js +0 -359
  807. package/dist/editor-completions/modifierCompletions.js +0 -197
  808. package/dist/editor-completions/types.js +0 -8
  809. package/dist/export/index.js +0 -212
  810. package/dist/extensions/index.d.ts +0 -16
  811. package/dist/extensions/index.js +0 -17
  812. package/dist/friendly-errors.js +0 -761
  813. package/dist/function-like.js +0 -84
  814. package/dist/generator/async-detection.js +0 -56
  815. package/dist/generator/code-utils.js +0 -551
  816. package/dist/generator/compile-target-registry.d.ts +0 -20
  817. package/dist/generator/compile-target-registry.js +0 -20
  818. package/dist/generator/control-flow.js +0 -358
  819. package/dist/generator/dev-mode-registry.d.ts +0 -27
  820. package/dist/generator/dev-mode-registry.js +0 -20
  821. package/dist/generator/scope-function-generator.js +0 -397
  822. package/dist/generator/unified.js +0 -1831
  823. package/dist/generator.d.ts +0 -54
  824. package/dist/generator.js +0 -101
  825. package/dist/jsdoc-parser.d.ts +0 -377
  826. package/dist/jsdoc-parser.js +0 -1189
  827. package/dist/jsdoc-port-sync/constants.js +0 -103
  828. package/dist/jsdoc-port-sync/diff.js +0 -319
  829. package/dist/jsdoc-port-sync/port-parser.js +0 -579
  830. package/dist/jsdoc-port-sync/rename.js +0 -256
  831. package/dist/jsdoc-port-sync/signature-parser.js +0 -559
  832. package/dist/jsdoc-port-sync/sync.js +0 -653
  833. package/dist/marketplace/manifest.js +0 -194
  834. package/dist/marketplace/registry.js +0 -198
  835. package/dist/marketplace/types.js +0 -9
  836. package/dist/marketplace/validator.js +0 -150
  837. package/dist/mcp/agent-channel.d.ts +0 -35
  838. package/dist/mcp/agent-channel.js +0 -61
  839. package/dist/mcp/auto-registration.d.ts +0 -3
  840. package/dist/mcp/auto-registration.js +0 -62
  841. package/dist/mcp/debug-session.js +0 -25
  842. package/dist/mcp/index.d.ts +0 -11
  843. package/dist/mcp/index.js +0 -10
  844. package/dist/mcp/pack-tools.js +0 -59
  845. package/dist/mcp/prompts.js +0 -68
  846. package/dist/mcp/response-utils.js +0 -97
  847. package/dist/mcp/run-registry.d.ts +0 -29
  848. package/dist/mcp/run-registry.js +0 -24
  849. package/dist/mcp/server.js +0 -63
  850. package/dist/mcp/tools-context.js +0 -51
  851. package/dist/mcp/tools-debug.js +0 -451
  852. package/dist/mcp/tools-diagram.js +0 -97
  853. package/dist/mcp/tools-docs.js +0 -62
  854. package/dist/mcp/tools-export.js +0 -222
  855. package/dist/mcp/tools-marketplace.js +0 -132
  856. package/dist/mcp/tools-model.d.ts +0 -3
  857. package/dist/mcp/tools-model.js +0 -279
  858. package/dist/mcp/tools-pattern.d.ts +0 -3
  859. package/dist/mcp/tools-pattern.js +0 -604
  860. package/dist/mcp/tools-query.js +0 -377
  861. package/dist/mcp/tools-resources.js +0 -41
  862. package/dist/mcp/tools-template.js +0 -119
  863. package/dist/mcp/tools-workflow-run.d.ts +0 -40
  864. package/dist/mcp/tools-workflow-run.js +0 -150
  865. package/dist/mcp/types.js +0 -2
  866. package/dist/mcp/workflow-executor.js +0 -242
  867. package/dist/migration/registry.js +0 -29
  868. package/dist/node-types-generator.js +0 -139
  869. package/dist/parser/tag-registry.js +0 -57
  870. package/dist/parser.d.ts +0 -232
  871. package/dist/parser.js +0 -2500
  872. package/dist/plugin/PluginPanel.d.ts +0 -12
  873. package/dist/plugin/PluginPanel.js +0 -5
  874. package/dist/plugin/index.d.ts +0 -13
  875. package/dist/plugin/index.js +0 -14
  876. package/dist/plugin/types.d.ts +0 -75
  877. package/dist/plugin/types.js +0 -8
  878. package/dist/resolve-package-types.js +0 -123
  879. package/dist/runtime/CancellationError.js +0 -20
  880. package/dist/runtime/ExecutionContext.js +0 -280
  881. package/dist/runtime/builtin-functions.js +0 -549
  882. package/dist/runtime/checkpoint.d.ts +0 -84
  883. package/dist/runtime/checkpoint.js +0 -225
  884. package/dist/runtime/debug-controller.js +0 -247
  885. package/dist/runtime/events.js +0 -2
  886. package/dist/runtime/function-registry.js +0 -66
  887. package/dist/runtime/parameter-resolver.js +0 -113
  888. package/dist/server/types.js +0 -5
  889. package/dist/server/webhook-server.js +0 -269
  890. package/dist/server/workflow-registry.js +0 -202
  891. package/dist/shared-project.js +0 -28
  892. package/dist/sugar-optimizer.js +0 -498
  893. package/dist/testing/assertions.js +0 -127
  894. package/dist/testing/mock-approval.js +0 -98
  895. package/dist/testing/mock-llm.js +0 -119
  896. package/dist/testing/recorder.js +0 -70
  897. package/dist/testing/replayer.js +0 -143
  898. package/dist/testing/token-tracker.js +0 -94
  899. package/dist/type-checker.d.ts +0 -42
  900. package/dist/type-checker.js +0 -190
  901. package/dist/type-mappings.js +0 -131
  902. package/dist/types/branded-ports.d.ts +0 -151
  903. package/dist/types/branded-ports.js +0 -121
  904. package/dist/types/index.d.ts +0 -5
  905. package/dist/types/index.js +0 -5
  906. package/dist/types.d.ts +0 -139
  907. package/dist/types.js +0 -15
  908. package/dist/utils/error-utils.js +0 -27
  909. package/dist/utils/lru-cache.js +0 -40
  910. package/dist/utils/port-ordering.js +0 -81
  911. package/dist/utils/port-tag-utils.js +0 -41
  912. package/dist/utils/string-distance.js +0 -56
  913. package/dist/validation/agent-detection.js +0 -115
  914. package/dist/validation/agent-rules.js +0 -262
  915. package/dist/validation/design-rules.js +0 -377
  916. package/dist/validation/rule-registry.js +0 -37
  917. package/dist/validator.d.ts +0 -113
  918. package/dist/validator.js +0 -1631
  919. package/docs/reference/patterns.md +0 -159
  920. package/scripts/postinstall.cjs +0 -86
  921. /package/dist/{shared-project.d.ts → parser/shared-project.d.ts} +0 -0
  922. /package/dist/{friendly-errors.d.ts → validation/friendly-errors.d.ts} +0 -0
@@ -0,0 +1,3300 @@
1
+ // src/cli/templates/providers/index.ts
2
+ function generateOpenAIProvider(opts) {
3
+ const model = opts.model || "gpt-4o";
4
+ const apiKey = opts.apiKeyEnvVar || "OPENAI_API_KEY";
5
+ return `
6
+ /* ============================================================
7
+ * OPENAI PROVIDER
8
+ * Set ${apiKey} environment variable before running
9
+ * ============================================================ */
10
+
11
+ const ${apiKey} = process.env.${apiKey};
12
+ if (!${apiKey}) {
13
+ throw new Error('Missing ${apiKey} environment variable');
14
+ }
15
+
16
+ const _defaultLlmProvider: LLMProvider = {
17
+ async chat(messages, options) {
18
+ const response = await fetch('https://api.openai.com/v1/chat/completions', {
19
+ method: 'POST',
20
+ headers: {
21
+ 'Authorization': \`Bearer \${${apiKey}}\`,
22
+ 'Content-Type': 'application/json',
23
+ },
24
+ body: JSON.stringify({
25
+ model: options?.model ?? '${model}',
26
+ messages: messages.map(m => ({
27
+ role: m.role,
28
+ content: m.content,
29
+ ...(m.toolCallId && { tool_call_id: m.toolCallId }),
30
+ })),
31
+ tools: options?.tools?.map(t => ({
32
+ type: 'function',
33
+ function: { name: t.name, description: t.description, parameters: t.parameters },
34
+ })),
35
+ temperature: options?.temperature,
36
+ max_tokens: options?.maxTokens,
37
+ }),
38
+ });
39
+
40
+ if (!response.ok) {
41
+ const error = await response.text();
42
+ throw new Error(\`OpenAI API error: \${response.status} \${error}\`);
43
+ }
44
+
45
+ const data = await response.json();
46
+ const choice = data.choices[0];
47
+
48
+ return {
49
+ content: choice.message.content,
50
+ toolCalls: choice.message.tool_calls?.map((tc: any) => ({
51
+ id: tc.id,
52
+ name: tc.function.name,
53
+ arguments: JSON.parse(tc.function.arguments),
54
+ })) ?? [],
55
+ finishReason: choice.finish_reason === 'tool_calls' ? 'tool_calls' : 'stop',
56
+ };
57
+ },
58
+ };
59
+
60
+ const llmProvider: LLMProvider = _defaultLlmProvider;
61
+ `;
62
+ }
63
+ function generateAnthropicProvider(opts) {
64
+ const model = opts.model || "claude-3-5-sonnet-20241022";
65
+ const apiKey = opts.apiKeyEnvVar || "ANTHROPIC_API_KEY";
66
+ return `
67
+ /* ============================================================
68
+ * ANTHROPIC PROVIDER
69
+ * Set ${apiKey} environment variable before running
70
+ * ============================================================ */
71
+
72
+ const ${apiKey} = process.env.${apiKey};
73
+ if (!${apiKey}) {
74
+ throw new Error('Missing ${apiKey} environment variable');
75
+ }
76
+
77
+ const _defaultLlmProvider: LLMProvider = {
78
+ async chat(messages, options) {
79
+ // Separate system message (Anthropic handles it differently)
80
+ const systemMessage = messages.find(m => m.role === 'system');
81
+ const chatMessages = messages.filter(m => m.role !== 'system');
82
+
83
+ const response = await fetch('https://api.anthropic.com/v1/messages', {
84
+ method: 'POST',
85
+ headers: {
86
+ 'x-api-key': ${apiKey},
87
+ 'anthropic-version': '2023-06-01',
88
+ 'Content-Type': 'application/json',
89
+ },
90
+ body: JSON.stringify({
91
+ model: options?.model ?? '${model}',
92
+ max_tokens: options?.maxTokens ?? 4096,
93
+ system: systemMessage?.content ?? options?.systemPrompt,
94
+ messages: chatMessages.map(m => {
95
+ if (m.role === 'tool') {
96
+ return {
97
+ role: 'user',
98
+ content: [{ type: 'tool_result', tool_use_id: m.toolCallId, content: m.content }],
99
+ };
100
+ }
101
+ return { role: m.role, content: m.content };
102
+ }),
103
+ tools: options?.tools?.map(t => ({
104
+ name: t.name,
105
+ description: t.description,
106
+ input_schema: { type: 'object', properties: t.parameters.properties, required: t.parameters.required },
107
+ })),
108
+ }),
109
+ });
110
+
111
+ if (!response.ok) {
112
+ const error = await response.text();
113
+ throw new Error(\`Anthropic API error: \${response.status} \${error}\`);
114
+ }
115
+
116
+ const data = await response.json();
117
+
118
+ let content: string | null = null;
119
+ const toolCalls: LLMToolCall[] = [];
120
+
121
+ for (const block of data.content) {
122
+ if (block.type === 'text') content = block.text;
123
+ if (block.type === 'tool_use') {
124
+ toolCalls.push({ id: block.id, name: block.name, arguments: block.input });
125
+ }
126
+ }
127
+
128
+ return {
129
+ content,
130
+ toolCalls,
131
+ finishReason: data.stop_reason === 'tool_use' ? 'tool_calls' : 'stop',
132
+ };
133
+ },
134
+ };
135
+
136
+ const llmProvider: LLMProvider = _defaultLlmProvider;
137
+ `;
138
+ }
139
+ function generateOllamaProvider(opts) {
140
+ const model = opts.model || "llama3.2";
141
+ return `
142
+ /* ============================================================
143
+ * OLLAMA PROVIDER (Local)
144
+ * Ensure Ollama is running: ollama serve
145
+ * Pull model first: ollama pull ${model}
146
+ * ============================================================ */
147
+
148
+ const OLLAMA_BASE_URL = process.env.OLLAMA_BASE_URL ?? 'http://localhost:11434';
149
+
150
+ const _defaultLlmProvider: LLMProvider = {
151
+ async chat(messages, options) {
152
+ const response = await fetch(\`\${OLLAMA_BASE_URL}/api/chat\`, {
153
+ method: 'POST',
154
+ headers: { 'Content-Type': 'application/json' },
155
+ body: JSON.stringify({
156
+ model: options?.model ?? '${model}',
157
+ messages: messages.map(m => ({ role: m.role, content: m.content })),
158
+ stream: false,
159
+ options: {
160
+ temperature: options?.temperature,
161
+ num_predict: options?.maxTokens,
162
+ },
163
+ }),
164
+ });
165
+
166
+ if (!response.ok) {
167
+ const error = await response.text();
168
+ throw new Error(\`Ollama error: \${response.status} \${error}\`);
169
+ }
170
+
171
+ const data = await response.json();
172
+
173
+ return {
174
+ content: data.message?.content ?? null,
175
+ toolCalls: [], // Ollama tool support varies by model
176
+ finishReason: 'stop',
177
+ };
178
+ },
179
+ };
180
+
181
+ const llmProvider: LLMProvider = _defaultLlmProvider;
182
+ `;
183
+ }
184
+ function generateMockProvider() {
185
+ return `
186
+ /* ============================================================
187
+ * MOCK PROVIDER (For Testing)
188
+ * Replace with real provider for production use
189
+ * ============================================================ */
190
+
191
+ const _defaultLlmProvider: LLMProvider = {
192
+ async chat(messages, options) {
193
+ const last = messages[messages.length - 1];
194
+
195
+ // Simulate tool call if message contains "search"
196
+ if (options?.tools && last.content.toLowerCase().includes('search')) {
197
+ return {
198
+ content: null,
199
+ toolCalls: [{
200
+ id: 'call_' + Date.now(),
201
+ name: 'search',
202
+ arguments: { query: last.content },
203
+ }],
204
+ finishReason: 'tool_calls',
205
+ };
206
+ }
207
+
208
+ return {
209
+ content: '[Mock response] ' + last.content,
210
+ toolCalls: [],
211
+ finishReason: 'stop',
212
+ };
213
+ },
214
+ };
215
+
216
+ const llmProvider: LLMProvider = _defaultLlmProvider;
217
+ `;
218
+ }
219
+ function getProviderCode(provider, model) {
220
+ const opts = { model: model || "" };
221
+ switch (provider) {
222
+ case "openai":
223
+ return generateOpenAIProvider({ ...opts, model: model || "gpt-4o" });
224
+ case "anthropic":
225
+ return generateAnthropicProvider({
226
+ ...opts,
227
+ model: model || "claude-3-5-sonnet-20241022"
228
+ });
229
+ case "ollama":
230
+ return generateOllamaProvider({ ...opts, model: model || "llama3.2" });
231
+ case "mock":
232
+ default:
233
+ return generateMockProvider();
234
+ }
235
+ }
236
+
237
+ // src/cli/templates/shared/llm-types.ts
238
+ var LLM_CORE_TYPES = `interface LLMMessage {
239
+ role: 'system' | 'user' | 'assistant' | 'tool';
240
+ content: string;
241
+ toolCallId?: string;
242
+ }
243
+
244
+ interface LLMResponse {
245
+ content: string | null;
246
+ toolCalls: LLMToolCall[];
247
+ finishReason: 'stop' | 'tool_calls' | 'length' | 'error';
248
+ usage?: { promptTokens: number; completionTokens: number };
249
+ }
250
+
251
+ interface LLMToolCall {
252
+ id: string;
253
+ name: string;
254
+ arguments: Record<string, unknown>;
255
+ }
256
+
257
+ interface LLMTool {
258
+ name: string;
259
+ description: string;
260
+ parameters: {
261
+ type: 'object';
262
+ properties: Record<string, { type: string }>;
263
+ required?: string[];
264
+ };
265
+ }
266
+
267
+ interface LLMProvider {
268
+ chat(
269
+ messages: LLMMessage[],
270
+ options?: { tools?: LLMTool[]; systemPrompt?: string; model?: string; temperature?: number; maxTokens?: number }
271
+ ): Promise<LLMResponse>;
272
+ }`;
273
+ var LLM_SIMPLE_TYPES = `interface LLMMessage {
274
+ role: 'system' | 'user' | 'assistant' | 'tool';
275
+ content: string;
276
+ toolCallId?: string;
277
+ }
278
+
279
+ interface LLMToolCall {
280
+ id: string;
281
+ name: string;
282
+ arguments: Record<string, unknown>;
283
+ }
284
+
285
+ interface LLMResponse {
286
+ content: string | null;
287
+ toolCalls: LLMToolCall[];
288
+ finishReason: 'stop' | 'tool_calls' | 'length' | 'error';
289
+ usage?: { promptTokens: number; completionTokens: number };
290
+ }
291
+
292
+ interface LLMProvider {
293
+ chat(messages: LLMMessage[], options?: { systemPrompt?: string; model?: string; temperature?: number; maxTokens?: number }): Promise<LLMResponse>;
294
+ }`;
295
+ var LLM_MOCK_PROVIDER = `const createMockProvider = (): LLMProvider => ({
296
+ async chat(messages) {
297
+ const lastMessage = messages[messages.length - 1];
298
+ return {
299
+ content: \`[Mock response to: \${(lastMessage?.content ?? '').slice(0, 50)}...]\`,
300
+ toolCalls: [],
301
+ finishReason: 'stop',
302
+ usage: { promptTokens: 10, completionTokens: 20 },
303
+ };
304
+ },
305
+ });
306
+
307
+ const llmProvider: LLMProvider = createMockProvider();`;
308
+ var LLM_MOCK_PROVIDER_WITH_TOOLS = `const createMockProvider = (): LLMProvider => ({
309
+ async chat(messages, options) {
310
+ const last = messages[messages.length - 1];
311
+ if (options?.tools && last.content.toLowerCase().includes('search')) {
312
+ return {
313
+ content: null,
314
+ toolCalls: [
315
+ {
316
+ id: 'call_' + Date.now(),
317
+ name: 'search',
318
+ arguments: { query: last.content },
319
+ },
320
+ ],
321
+ finishReason: 'tool_calls',
322
+ usage: { promptTokens: 15, completionTokens: 30 },
323
+ };
324
+ }
325
+
326
+ return {
327
+ content: '[Mock answer] ' + last.content,
328
+ toolCalls: [],
329
+ finishReason: 'stop',
330
+ usage: { promptTokens: 10, completionTokens: 20 },
331
+ };
332
+ },
333
+ });
334
+
335
+ const llmProvider: LLMProvider = createMockProvider();`;
336
+
337
+ // src/cli/templates/workflows/ai-agent.ts
338
+ var aiConfigSchema = {
339
+ provider: {
340
+ type: "select",
341
+ label: "LLM Provider",
342
+ description: "Choose your LLM provider",
343
+ default: "mock",
344
+ options: [
345
+ { value: "openai", label: "OpenAI" },
346
+ { value: "anthropic", label: "Anthropic" },
347
+ { value: "ollama", label: "Ollama (Local)" },
348
+ { value: "mock", label: "Mock (Testing)" }
349
+ ]
350
+ },
351
+ model: {
352
+ type: "string",
353
+ label: "Model",
354
+ description: "Model identifier",
355
+ default: "gpt-4o",
356
+ placeholder: "e.g., gpt-4o, claude-3-5-sonnet-20241022, llama3.2",
357
+ dependsOn: {
358
+ field: "provider",
359
+ values: ["openai", "anthropic", "ollama"]
360
+ }
361
+ }
362
+ };
363
+ var aiAgentTemplate = {
364
+ id: "ai-agent",
365
+ name: "AI Agent (Tool Calling)",
366
+ description: "Stateful LLM agent with explicit reasoning loop and tool execution",
367
+ category: "ai",
368
+ configSchema: aiConfigSchema,
369
+ generate: ({ workflowName, config }) => {
370
+ const provider = config?.provider || "mock";
371
+ const model = config?.model || "";
372
+ const providerCode = provider === "mock" ? `
373
+ /* ============================================================
374
+ * MOCK PROVIDER (REPLACE IN REAL USE)
375
+ * ============================================================
376
+ */
377
+
378
+ ${LLM_MOCK_PROVIDER_WITH_TOOLS}
379
+ ` : getProviderCode(provider, model);
380
+ return `
381
+ /* ============================================================
382
+ * CORE TYPES
383
+ * ============================================================
384
+ */
385
+
386
+ ${LLM_CORE_TYPES}
387
+
388
+ type TerminationReason =
389
+ | 'completed'
390
+ | 'max_iterations'
391
+ | 'tool_error'
392
+ | 'llm_error'
393
+ | 'aborted';
394
+
395
+ /* ============================================================
396
+ * AGENT STATE
397
+ * ============================================================
398
+ */
399
+
400
+ interface AgentState {
401
+ messages: LLMMessage[];
402
+ iteration: number;
403
+ toolsUsed: string[];
404
+ terminated: boolean;
405
+ terminationReason?: TerminationReason;
406
+ finalResponse?: string;
407
+ }
408
+
409
+ ${providerCode}
410
+
411
+ const SYSTEM_PROMPT = \`You are a helpful AI assistant with access to tools.
412
+ Use tools when necessary. Respond directly when the task is complete.\`;
413
+
414
+ const MAX_ITERATIONS = 10;
415
+
416
+ /* ============================================================
417
+ * TOOLS
418
+ * ============================================================
419
+ */
420
+
421
+ const AVAILABLE_TOOLS: LLMTool[] = [
422
+ {
423
+ name: 'search',
424
+ description: 'Search for information',
425
+ parameters: {
426
+ type: 'object',
427
+ properties: {
428
+ query: { type: 'string' },
429
+ },
430
+ required: ['query'],
431
+ },
432
+ },
433
+ ];
434
+
435
+ type ToolResult =
436
+ | { ok: true; value: string }
437
+ | { ok: false; error: string };
438
+
439
+ type ToolFn = (args: Record<string, unknown>) => Promise<ToolResult>;
440
+
441
+ const TOOL_IMPLEMENTATIONS: Record<string, ToolFn> = {
442
+ async search(args) {
443
+ if (typeof args.query !== 'string') {
444
+ return { ok: false, error: 'Invalid query' };
445
+ }
446
+ return { ok: true, value: '[Search results for: ' + args.query + ']' };
447
+ },
448
+ };
449
+
450
+ /* ============================================================
451
+ * NODES
452
+ * ============================================================
453
+ */
454
+
455
+ /**
456
+ * Agent loop that orchestrates LLM calls and tool execution
457
+ * Uses scoped ports to handle iteration internally
458
+ *
459
+ * @flowWeaver nodeType
460
+ * @label Agent Loop
461
+ * @input userMessage [order:1] - User's input message
462
+ * @input [maxIterations] [order:2] - Maximum loop iterations (default: 10)
463
+ * @input success scope:iteration [order:0] - From LLM onSuccess
464
+ * @input failure scope:iteration [order:1] - From LLM onFailure
465
+ * @input llmResponse scope:iteration [order:2] - LLM response
466
+ * @input toolMessages scope:iteration [order:3] - Tool results
467
+ * @input execute [order:0] - Execute
468
+ * @output start scope:iteration [order:0] - Triggers iteration
469
+ * @output state scope:iteration [order:1] - Current agent state
470
+ * @output response [order:2] - Final response when done
471
+ * @output onSuccess [order:0] - On Success
472
+ * @output onFailure [order:1] - On Failure
473
+ */
474
+ async function agentLoop(
475
+ execute: boolean,
476
+ userMessage: string,
477
+ maxIterations: number = MAX_ITERATIONS,
478
+ iteration: (start: boolean, state: AgentState) => Promise<{
479
+ success: boolean;
480
+ failure: boolean;
481
+ llmResponse: LLMResponse | null;
482
+ toolMessages: LLMMessage[];
483
+ }>
484
+ ): Promise<{ onSuccess: boolean; onFailure: boolean; response: string }> {
485
+ if (!execute) {
486
+ return { onSuccess: false, onFailure: false, response: '' };
487
+ }
488
+
489
+ let state: AgentState = {
490
+ messages: [{ role: 'user', content: userMessage }],
491
+ iteration: 0,
492
+ toolsUsed: [],
493
+ terminated: false,
494
+ };
495
+
496
+ while (state.iteration < maxIterations) {
497
+ const result = await iteration(true, state);
498
+
499
+ state.iteration++;
500
+
501
+ // Handle LLM failure
502
+ if (result.failure) {
503
+ return { onSuccess: false, onFailure: true, response: 'LLM error occurred' };
504
+ }
505
+
506
+ // Add assistant message if present
507
+ if (result.llmResponse?.content) {
508
+ state.messages.push({ role: 'assistant', content: result.llmResponse.content });
509
+ }
510
+
511
+ // Add tool messages
512
+ if (result.toolMessages && result.toolMessages.length > 0) {
513
+ state.messages.push(...result.toolMessages);
514
+ }
515
+
516
+ // Check termination: no tool calls means we're done
517
+ if (result.llmResponse && result.llmResponse.toolCalls.length === 0 && result.llmResponse.content) {
518
+ return { onSuccess: true, onFailure: false, response: result.llmResponse.content };
519
+ }
520
+ }
521
+
522
+ return { onSuccess: true, onFailure: false, response: 'Max iterations reached' };
523
+ }
524
+
525
+ /**
526
+ * Calls the LLM with current state
527
+ *
528
+ * @flowWeaver nodeType
529
+ * @label Call LLM
530
+ * @input state [order:1] - Current agent state
531
+ * @input execute [order:0] - Execute
532
+ * @output response [order:2] - LLM response
533
+ * @output toolCalls [order:3] - Tool calls from LLM
534
+ * @output onSuccess [order:0] - On Success
535
+ * @output onFailure [order:1] - On Failure
536
+ */
537
+ async function callLLM(
538
+ execute: boolean,
539
+ state: AgentState
540
+ ): Promise<{
541
+ onSuccess: boolean;
542
+ onFailure: boolean;
543
+ response: LLMResponse | null;
544
+ toolCalls: LLMToolCall[];
545
+ }> {
546
+ if (!execute) {
547
+ return { onSuccess: false, onFailure: false, response: null, toolCalls: [] };
548
+ }
549
+
550
+ try {
551
+ const response = await llmProvider.chat(state.messages, {
552
+ tools: AVAILABLE_TOOLS,
553
+ systemPrompt: SYSTEM_PROMPT,
554
+ });
555
+
556
+ return { onSuccess: true, onFailure: false, response, toolCalls: response.toolCalls };
557
+ } catch {
558
+ return { onSuccess: false, onFailure: true, response: null, toolCalls: [] };
559
+ }
560
+ }
561
+
562
+ /**
563
+ * Executes tool calls
564
+ *
565
+ * @flowWeaver nodeType
566
+ * @label Execute Tools
567
+ * @input calls [order:1] - Tool calls to execute
568
+ * @input execute [order:0] - Execute
569
+ * @output messages [order:2] - Tool response messages
570
+ * @output onSuccess [order:0] - On Success
571
+ * @output onFailure [order:1] - On Failure
572
+ */
573
+ async function executeTools(
574
+ execute: boolean,
575
+ calls: LLMToolCall[]
576
+ ): Promise<{
577
+ onSuccess: boolean;
578
+ onFailure: boolean;
579
+ messages: LLMMessage[];
580
+ }> {
581
+ if (!execute || !calls || calls.length === 0) {
582
+ return { onSuccess: true, onFailure: false, messages: [] };
583
+ }
584
+
585
+ const messages: LLMMessage[] = [];
586
+
587
+ for (const call of calls) {
588
+ const impl = TOOL_IMPLEMENTATIONS[call.name];
589
+ if (!impl) {
590
+ messages.push({
591
+ role: 'tool',
592
+ content: 'Unknown tool: ' + call.name,
593
+ toolCallId: call.id,
594
+ });
595
+ continue;
596
+ }
597
+
598
+ const result = await impl(call.arguments);
599
+
600
+ messages.push({
601
+ role: 'tool',
602
+ content: result.ok ? result.value : 'Error: ' + result.error,
603
+ toolCallId: call.id,
604
+ });
605
+ }
606
+
607
+ return { onSuccess: true, onFailure: false, messages };
608
+ }
609
+
610
+ /* ============================================================
611
+ * WORKFLOW
612
+ * ============================================================
613
+ */
614
+
615
+ /**
616
+ * AI Agent that uses tools to accomplish tasks
617
+ *
618
+ * @flowWeaver workflow
619
+ * @node loop agentLoop [color: "purple"] [icon: "smartToy"]
620
+ * @node llm callLLM loop.iteration [color: "blue"] [icon: "psychology"]
621
+ * @node tools executeTools loop.iteration [color: "orange"] [icon: "build"] [suppress: "AGENT_UNGUARDED_TOOL_EXECUTOR"]
622
+ * @connect Start.execute -> loop.execute
623
+ * @connect Start.userMessage -> loop.userMessage
624
+ * @connect loop.start:iteration -> llm.execute
625
+ * @connect loop.state:iteration -> llm.state
626
+ * @connect llm.toolCalls -> tools.calls
627
+ * @connect llm.onSuccess -> tools.execute
628
+ * @connect llm.response -> loop.llmResponse:iteration
629
+ * @connect llm.onSuccess -> loop.success:iteration
630
+ * @connect llm.onFailure -> loop.failure:iteration
631
+ * @connect tools.messages -> loop.toolMessages:iteration
632
+ * @connect tools.onFailure -> loop.failure:iteration
633
+ * @connect loop.response -> Exit.response
634
+ * @connect loop.onSuccess -> Exit.onSuccess
635
+ * @connect loop.onFailure -> Exit.onFailure
636
+ * @param execute [order:0] - Execute
637
+ * @param userMessage [order:1] - User's message to the agent
638
+ * @returns onSuccess [order:0] - Agent completed successfully
639
+ * @returns onFailure [order:1] - Agent encountered an error
640
+ * @returns response [order:2] - Agent's final response
641
+ */
642
+ export async function ${workflowName}(
643
+ execute: boolean,
644
+ params: { userMessage: string }
645
+ ): Promise<{
646
+ onSuccess: boolean;
647
+ onFailure: boolean;
648
+ response: string;
649
+ }> {
650
+ throw new Error('Compile with: fw compile <file>');
651
+ }
652
+ `.trim();
653
+ }
654
+ };
655
+
656
+ // src/cli/templates/shared/case.ts
657
+ function toCamelCase(str) {
658
+ const leadingMatch = str.match(/^[_$]+/);
659
+ const leading = leadingMatch ? leadingMatch[0] : "";
660
+ const rest = leading ? str.slice(leading.length) : str;
661
+ const result = rest.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : "").replace(/^[^a-zA-Z_$]+/, "").replace(/^./, (c) => c.toLowerCase());
662
+ const final = leading + result;
663
+ return final || "_" + str.replace(/[^a-zA-Z0-9_$]/g, "");
664
+ }
665
+ function toPascalCase(str) {
666
+ const camel = toCamelCase(str);
667
+ return camel.charAt(0).toUpperCase() + camel.slice(1);
668
+ }
669
+
670
+ // src/cli/templates/workflows/sequential.ts
671
+ var configSchema = {
672
+ nodes: {
673
+ type: "string",
674
+ label: "Node Names",
675
+ description: 'Comma-separated list of node function names (e.g. "fetch,parse,store")',
676
+ placeholder: "validateData,transformData,outputResult"
677
+ },
678
+ input: {
679
+ type: "string",
680
+ label: "Input Port Name",
681
+ description: "Name of the input data port",
682
+ default: "data",
683
+ placeholder: "data"
684
+ },
685
+ output: {
686
+ type: "string",
687
+ label: "Output Port Name",
688
+ description: "Name of the output data port",
689
+ default: "result",
690
+ placeholder: "result"
691
+ }
692
+ };
693
+ function generateDefaultTemplate(workflowName, asyncKeyword, returnType) {
694
+ return `
695
+ // Use @expression for most functions, normal mode only for error-with-data or void side-effects
696
+
697
+ /**
698
+ * Validates input data
699
+ * Normal mode: explicit error routing with data on failure
700
+ *
701
+ * @flowWeaver nodeType
702
+ * @label Validate
703
+ * @input data [order:1] - Data to validate
704
+ * @input execute [order:0] - Execute
705
+ * @output data [order:2] - Validated data
706
+ * @output isValid [order:3] - Validation passed
707
+ * @output error [order:4] - Validation error message
708
+ * @output onSuccess [order:0] - On Success
709
+ * @output onFailure [order:1] - On Failure
710
+ */
711
+ function validateData(
712
+ execute: boolean,
713
+ data: any
714
+ ): { onSuccess: boolean; onFailure: boolean; data: any; isValid: boolean; error: string | null } {
715
+ if (!execute) {
716
+ return { onSuccess: false, onFailure: false, data: null, isValid: false, error: null };
717
+ }
718
+
719
+ // TODO: Add validation logic
720
+ if (!data) {
721
+ return { onSuccess: false, onFailure: true, data: null, isValid: false, error: "Data is required" };
722
+ }
723
+
724
+ return { onSuccess: true, onFailure: false, data, isValid: true, error: null };
725
+ }
726
+
727
+ /**
728
+ * Transforms validated data
729
+ *
730
+ * @flowWeaver nodeType
731
+ * @expression
732
+ * @label Transform
733
+ * @input data [order:0] - Data to transform
734
+ * @output data [order:0] - Transformed data
735
+ */
736
+ function transformData(data: any): { data: any } {
737
+ // TODO: Add transformation logic
738
+ return { data: { ...data, processedAt: new Date().toISOString() } };
739
+ }
740
+
741
+ /**
742
+ * Outputs the final result
743
+ *
744
+ * @flowWeaver nodeType
745
+ * @expression
746
+ * @label Output
747
+ * @input data [order:0] - Data to output
748
+ * @output result [order:0] - Final result
749
+ */
750
+ function outputResult(data: any): { result: any } {
751
+ return { result: data };
752
+ }
753
+
754
+ /**
755
+ * @flowWeaver workflow
756
+ * @node validator validateData [color: "green"] [icon: "verified"] [suppress: "UNUSED_OUTPUT_PORT"]
757
+ * @node transformer transformData [color: "blue"] [icon: "sync"]
758
+ * @node outputter outputResult [color: "cyan"] [icon: "inventory"]
759
+ * @path Start -> validator -> transformer -> outputter -> Exit
760
+ * @path Start -> validator:fail -> Exit
761
+ * @param execute [order:0] - Execute
762
+ * @param data [order:1] - Input data
763
+ * @returns onSuccess [order:0] - On Success
764
+ * @returns onFailure [order:1] - On Failure
765
+ * @returns result [order:2] - Processed result
766
+ * @returns error [order:3] - Error message if failed
767
+ */
768
+ export ${asyncKeyword}function ${workflowName}(
769
+ execute: boolean,
770
+ params: { data: any }
771
+ ): ${returnType} {
772
+ throw new Error("Compile with: fw compile <file>");
773
+ }
774
+ `.trim();
775
+ }
776
+ function generateCustomTemplate(workflowName, asyncKeyword, returnType, nodeNames, inputPort, outputPort) {
777
+ const nodeTypeDefs = nodeNames.map((name, i) => {
778
+ const isFirst = i === 0;
779
+ const isLast = i === nodeNames.length - 1;
780
+ const inputPortName = isFirst ? inputPort : "data";
781
+ const outputPortName = isLast ? outputPort : "data";
782
+ return `/**
783
+ * ${name} step
784
+ *
785
+ * @flowWeaver nodeType
786
+ * @expression
787
+ * @label ${name.charAt(0).toUpperCase() + name.slice(1)}
788
+ * @input ${inputPortName} [order:0] - Input data
789
+ * @output ${outputPortName} [order:0] - Output data
790
+ */
791
+ function ${name}(${inputPortName}: any): { ${outputPortName}: any } {
792
+ // TODO: Implement ${name} logic
793
+ return { ${outputPortName}: ${inputPortName} };
794
+ }`;
795
+ });
796
+ const stepColors = ["green", "blue", "cyan", "orange", "purple", "teal", "pink", "yellow"];
797
+ const nodeAnnotations = nodeNames.map((name, i) => {
798
+ const color = stepColors[i % stepColors.length];
799
+ return ` * @node step${i} ${name} [color: "${color}"] [icon: "settings"]`;
800
+ }).join("\n");
801
+ const pathNodes = ["Start", ...nodeNames.map((_, i) => `step${i}`), "Exit"];
802
+ const connections = [];
803
+ connections.push(` * @path ${pathNodes.join(" -> ")}`);
804
+ connections.push(` * @path Start -> step0:fail -> Exit`);
805
+ return `${nodeTypeDefs.join("\n\n")}
806
+
807
+ /**
808
+ * @flowWeaver workflow
809
+ ${nodeAnnotations}
810
+ ${connections.join("\n")}
811
+ * @param execute [order:0] - Execute
812
+ * @param ${inputPort} [order:1] - Input data
813
+ * @returns onSuccess [order:0] - On Success
814
+ * @returns onFailure [order:1] - On Failure
815
+ * @returns ${outputPort} [order:2] - Processed result
816
+ */
817
+ export ${asyncKeyword}function ${workflowName}(
818
+ execute: boolean,
819
+ params: { ${inputPort}: any }
820
+ ): ${returnType} {
821
+ throw new Error("Compile with: fw compile <file>");
822
+ }`.trim();
823
+ }
824
+ var sequentialTemplate = {
825
+ id: "sequential",
826
+ name: "Sequential Pipeline",
827
+ description: "Linear pipeline: validate -> transform -> output",
828
+ category: "data-processing",
829
+ configSchema,
830
+ generate: (opts) => {
831
+ const { workflowName, async: isAsync, config } = opts;
832
+ const asyncKeyword = isAsync ? "async " : "";
833
+ const returnTypeFor = (outputPort2, withError) => {
834
+ const body = `onSuccess: boolean, onFailure: boolean, ${outputPort2}: any${withError ? ", error: string | null" : ""}`;
835
+ return isAsync ? `Promise<{ ${body} }>` : `{ ${body} }`;
836
+ };
837
+ const customNodes = config?.nodes;
838
+ const inputPort = config?.input || "data";
839
+ const outputPort = config?.output || "result";
840
+ if (customNodes && Array.isArray(customNodes) && customNodes.length > 0) {
841
+ return generateCustomTemplate(
842
+ workflowName,
843
+ asyncKeyword,
844
+ returnTypeFor(outputPort, false),
845
+ customNodes,
846
+ inputPort,
847
+ outputPort
848
+ );
849
+ }
850
+ if (inputPort !== "data" || outputPort !== "result") {
851
+ return generateCustomTemplate(
852
+ workflowName,
853
+ asyncKeyword,
854
+ returnTypeFor(outputPort, false),
855
+ ["validateData", "transformData", "outputResult"],
856
+ inputPort,
857
+ outputPort
858
+ );
859
+ }
860
+ return generateDefaultTemplate(workflowName, asyncKeyword, returnTypeFor("result", true));
861
+ }
862
+ };
863
+
864
+ // src/cli/templates/workflows/foreach.ts
865
+ var foreachTemplate = {
866
+ id: "foreach",
867
+ name: "ForEach Batch",
868
+ description: "Batch processing with iteration over arrays",
869
+ category: "data-processing",
870
+ generate: (opts) => {
871
+ const { workflowName, async: isAsync } = opts;
872
+ const asyncKeyword = isAsync ? "async " : "";
873
+ const returnType = isAsync ? "Promise<{ onSuccess: boolean; onFailure: boolean; results: any[]; successCount: number; failedCount: number }>" : "{ onSuccess: boolean; onFailure: boolean; results: any[]; successCount: number; failedCount: number }";
874
+ return `
875
+ /**
876
+ * Iterates over items and processes each one.
877
+ * Normal mode on purpose: a scope owner drives its child through scoped STEP ports.
878
+ *
879
+ * @flowWeaver nodeType
880
+ * @label For Each Item
881
+ * @input items [order:1] - Array of items to iterate
882
+ * @input success scope:processItem [order:0] - From child onSuccess
883
+ * @input failure scope:processItem [order:1] - From child onFailure
884
+ * @input result scope:processItem [order:2] - Result from child
885
+ * @input execute [order:0] - Execute
886
+ * @output start scope:processItem [order:0] - Triggers child execute
887
+ * @output item scope:processItem [order:1] - Current item to process
888
+ * @output results [order:2] - Collected results after iteration
889
+ * @output onSuccess [order:0] - On Success
890
+ * @output onFailure [order:1] - On Failure
891
+ */
892
+ function forEachItem(
893
+ execute: boolean,
894
+ items: any[],
895
+ processItem: (start: boolean, item: any) => { success: boolean; failure: boolean; result: any }
896
+ ): { onSuccess: boolean; onFailure: boolean; results: any[] } {
897
+ if (!execute) {
898
+ return { onSuccess: false, onFailure: false, results: [] };
899
+ }
900
+
901
+ const results: any[] = [];
902
+ for (const item of items) {
903
+ const r = processItem(true, item);
904
+ results.push(r.result);
905
+ }
906
+
907
+ return { onSuccess: true, onFailure: false, results };
908
+ }
909
+
910
+ /**
911
+ * Processes a single item. A throw here aborts the whole batch with that
912
+ * error; to record a per-item failure instead, return it as part of the result.
913
+ *
914
+ * @flowWeaver nodeType
915
+ * @expression
916
+ * @label Process Item
917
+ * @input item - Item to process
918
+ * @output result - Processed result
919
+ */
920
+ function processItem(item: any): { result: any } {
921
+ // TODO: Add your processing logic here
922
+ return { result: { ...item, processed: true } };
923
+ }
924
+
925
+ /**
926
+ * Aggregates results from iteration
927
+ *
928
+ * @flowWeaver nodeType
929
+ * @expression
930
+ * @label Aggregate Results
931
+ * @input results - Array of processed results
932
+ * @output successCount - Number of successes
933
+ * @output failedCount - Number of failures
934
+ */
935
+ function aggregateResults(results: any[]): { successCount: number; failedCount: number } {
936
+ const successCount = results.filter(r => r?.processed).length;
937
+ return { successCount, failedCount: results.length - successCount };
938
+ }
939
+
940
+ /**
941
+ * @flowWeaver workflow
942
+ * @node iterator forEachItem [color: "purple"] [icon: "repeat"] [suppress: "DESIGN_SCOPE_NO_FAILURE_EXIT"]
943
+ * @node processor processItem iterator.processItem [color: "blue"] [icon: "settings"]
944
+ * @node aggregator aggregateResults [color: "teal"] [icon: "inventory"]
945
+ * @path Start -> iterator -> aggregator -> Exit
946
+ * @connect iterator.start:processItem -> processor.execute
947
+ * @connect iterator.item:processItem -> processor.item
948
+ * @connect processor.result -> iterator.result:processItem
949
+ * @connect processor.onSuccess -> iterator.success:processItem
950
+ * @connect processor.onFailure -> iterator.failure:processItem
951
+ * @param execute [order:0] - Execute
952
+ * @param items [order:1] - Array of items to process
953
+ * @returns onSuccess [order:0] - On Success
954
+ * @returns onFailure [order:1] - On Failure
955
+ * @returns results [order:2] - Processed results
956
+ * @returns successCount [order:3] - Number of successful items
957
+ * @returns failedCount [order:4] - Number of failed items
958
+ */
959
+ export ${asyncKeyword}function ${workflowName}(
960
+ execute: boolean,
961
+ params: { items: any[] }
962
+ ): ${returnType} {
963
+ throw new Error("Compile with: fw compile <file>");
964
+ }
965
+ `.trim();
966
+ }
967
+ };
968
+
969
+ // src/cli/templates/workflows/conditional.ts
970
+ var conditionalTemplate = {
971
+ id: "conditional",
972
+ name: "Conditional Router",
973
+ description: "Route data based on conditions with branching paths",
974
+ category: "automation",
975
+ generate: (opts) => {
976
+ const { workflowName, async: isAsync } = opts;
977
+ const asyncKeyword = isAsync ? "async " : "";
978
+ const returnType = isAsync ? "Promise<{ onSuccess: boolean; onFailure: boolean; successResult?: any; failureResult?: any }>" : "{ onSuccess: boolean; onFailure: boolean; successResult?: any; failureResult?: any }";
979
+ return `
980
+ /**
981
+ * Evaluates condition and routes data.
982
+ * onSuccess = condition met (true path), onFailure = condition not met (false path).
983
+ * Errors are caught internally and returned via the onFailure path.
984
+ *
985
+ * @flowWeaver nodeType
986
+ * @label Evaluate Condition
987
+ * @input data [order:1] - Data to evaluate
988
+ * @input execute [order:0] - Execute
989
+ * @output conditionTrue [order:2] - Data if condition passed
990
+ * @output conditionFalse [order:3] - Data if condition failed
991
+ * @output conditionMet [order:4] - Whether condition was met
992
+ * @output onSuccess [order:0] - Condition passed (routes to success handler)
993
+ * @output onFailure [order:1] - Condition not met (routes to failure handler)
994
+ */
995
+ function evaluateCondition(
996
+ execute: boolean,
997
+ data: any
998
+ ): { onSuccess: boolean; onFailure: boolean; conditionTrue: any; conditionFalse: any; conditionMet: boolean } {
999
+ if (!execute) {
1000
+ return { onSuccess: false, onFailure: false, conditionTrue: null, conditionFalse: null, conditionMet: false };
1001
+ }
1002
+
1003
+ try {
1004
+ // TODO: Define your condition logic
1005
+ const conditionMet = Boolean(data && data.isValid);
1006
+
1007
+ if (conditionMet) {
1008
+ return { onSuccess: true, onFailure: false, conditionTrue: data, conditionFalse: null, conditionMet: true };
1009
+ } else {
1010
+ return { onSuccess: false, onFailure: true, conditionTrue: null, conditionFalse: data, conditionMet: false };
1011
+ }
1012
+ } catch (err) {
1013
+ // On error, route to failure path with the original data
1014
+ return { onSuccess: false, onFailure: true, conditionTrue: null, conditionFalse: data, conditionMet: false };
1015
+ }
1016
+ }
1017
+
1018
+ /**
1019
+ * Handles success path
1020
+ *
1021
+ * @flowWeaver nodeType
1022
+ * @label Handle Success
1023
+ * @input data [order:1] - Data from success path
1024
+ * @input execute [order:0] - Execute
1025
+ * @output result [order:2] - Success result
1026
+ * @output onSuccess [order:0] - On Success
1027
+ * @output onFailure [order:1] - On Failure
1028
+ */
1029
+ function handleSuccess(
1030
+ execute: boolean,
1031
+ data: any
1032
+ ): { onSuccess: boolean; onFailure: boolean; result: any } {
1033
+ if (!execute) {
1034
+ return { onSuccess: false, onFailure: false, result: null };
1035
+ }
1036
+
1037
+ // TODO: Handle success case
1038
+ return { onSuccess: true, onFailure: false, result: { status: "success", data } };
1039
+ }
1040
+
1041
+ /**
1042
+ * Handles failure path
1043
+ *
1044
+ * @flowWeaver nodeType
1045
+ * @label Handle Failure
1046
+ * @input data [order:1] - Data from failure path
1047
+ * @input execute [order:0] - Execute
1048
+ * @output result [order:2] - Failure result
1049
+ * @output onSuccess [order:0] - On Success
1050
+ * @output onFailure [order:1] - On Failure
1051
+ */
1052
+ function handleFailure(
1053
+ execute: boolean,
1054
+ data: any
1055
+ ): { onSuccess: boolean; onFailure: boolean; result: any } {
1056
+ if (!execute) {
1057
+ return { onSuccess: false, onFailure: false, result: null };
1058
+ }
1059
+
1060
+ // TODO: Handle failure case
1061
+ return { onSuccess: true, onFailure: false, result: { status: "failure", data } };
1062
+ }
1063
+
1064
+ /**
1065
+ * @flowWeaver workflow
1066
+ * @node router evaluateCondition [color: "orange"] [icon: "altRoute"] [suppress: "UNUSED_OUTPUT_PORT"]
1067
+ * @node successHandler handleSuccess [color: "green"] [icon: "checkCircle"]
1068
+ * @node failureHandler handleFailure [color: "red"] [icon: "error"]
1069
+ * @connect Start.execute -> router.execute
1070
+ * @connect Start.data -> router.data
1071
+ * @connect router.onSuccess -> successHandler.execute
1072
+ * @connect router.conditionTrue -> successHandler.data
1073
+ * @connect router.onFailure -> failureHandler.execute
1074
+ * @connect router.conditionFalse -> failureHandler.data
1075
+ * @connect successHandler.result -> Exit.successResult
1076
+ * @connect successHandler.onSuccess -> Exit.onSuccess
1077
+ * @connect failureHandler.result -> Exit.failureResult
1078
+ * @connect failureHandler.onSuccess -> Exit.onFailure
1079
+ * @param execute [order:0] - Execute
1080
+ * @param data [order:1] - Input data to route
1081
+ * @returns onSuccess [order:0] - Success path completed
1082
+ * @returns onFailure [order:1] - Failure path completed
1083
+ * @returns successResult [order:2] - Result from success path
1084
+ * @returns failureResult [order:3] - Result from failure path
1085
+ */
1086
+ export ${asyncKeyword}function ${workflowName}(
1087
+ execute: boolean,
1088
+ params: { data: any }
1089
+ ): ${returnType} {
1090
+ throw new Error("Compile with: fw compile <file>");
1091
+ }
1092
+ `.trim();
1093
+ }
1094
+ };
1095
+
1096
+ // src/cli/templates/workflows/ai-react.ts
1097
+ var aiReactTemplate = {
1098
+ id: "ai-react",
1099
+ name: "ReAct Agent",
1100
+ description: "Reasoning + Acting agent with explicit thought process",
1101
+ category: "ai",
1102
+ configSchema: aiConfigSchema,
1103
+ generate: (opts) => {
1104
+ const { workflowName, config } = opts;
1105
+ const provider = config?.provider || "mock";
1106
+ const model = config?.model || "";
1107
+ const providerCode = provider === "mock" ? `
1108
+ // Mock provider. Replace with a real provider for production.
1109
+ const createMockReactProvider = (): LLMProvider => ({
1110
+ async chat(messages) {
1111
+ const lastMessage = messages[messages.length - 1];
1112
+ return {
1113
+ content: \`Thought: Processing the request\\nAction: FINISH\\nAction Input: [Mock answer to: \${lastMessage.content.slice(0, 30)}...]\`,
1114
+ toolCalls: [],
1115
+ finishReason: 'stop',
1116
+ };
1117
+ },
1118
+ });
1119
+
1120
+ const llmProvider: LLMProvider = createMockReactProvider();
1121
+ ` : getProviderCode(provider, model);
1122
+ return `
1123
+ // ============================================================
1124
+ // ReAct Agent: Thought \u2192 Action \u2192 Observation loop
1125
+ // ============================================================
1126
+ //
1127
+ // The agent follows the ReAct pattern (Yao et al., 2022):
1128
+ // 1. Think: reason about the current state
1129
+ // 2. Act: call a tool or FINISH
1130
+ // 3. Observe: receive tool output, feed back into next thought
1131
+ //
1132
+ // The reactLoop node manages iteration and message accumulation.
1133
+ // think + act run inside the loop's scoped iteration.
1134
+
1135
+ // ============================================================
1136
+ // LLM TYPES
1137
+ // ============================================================
1138
+
1139
+ ${LLM_CORE_TYPES}
1140
+
1141
+ ${providerCode}
1142
+ const MAX_STEPS = 10;
1143
+
1144
+ const REACT_PROMPT = \`You are a ReAct (Reasoning + Acting) agent.
1145
+
1146
+ For each step, you MUST respond in this exact format:
1147
+ Thought: [Your reasoning about what to do next]
1148
+ Action: [tool_name] or [FINISH]
1149
+ Action Input: [input for the tool, or final answer if FINISH]
1150
+
1151
+ Available tools: search, calculate
1152
+
1153
+ When you have the final answer:
1154
+ Thought: I now have enough information to answer
1155
+ Action: FINISH
1156
+ Action Input: [Your final answer here]\`;
1157
+
1158
+ // Parse ReAct response format
1159
+ function parseReactResponse(content: string): {
1160
+ thought: string;
1161
+ action: string;
1162
+ actionInput: string;
1163
+ } {
1164
+ const thoughtMatch = content.match(/Thought:\\s*(.+?)(?=\\nAction:|$)/s);
1165
+ const actionMatch = content.match(/Action:\\s*(.+?)(?=\\nAction Input:|$)/s);
1166
+ const inputMatch = content.match(/Action Input:\\s*(.+?)$/s);
1167
+
1168
+ return {
1169
+ thought: thoughtMatch?.[1]?.trim() ?? '',
1170
+ action: actionMatch?.[1]?.trim() ?? 'FINISH',
1171
+ actionInput: inputMatch?.[1]?.trim() ?? '',
1172
+ };
1173
+ }
1174
+
1175
+ // ============================================================
1176
+ // TOOL IMPLEMENTATIONS
1177
+ // ============================================================
1178
+
1179
+ // Replace with real tools
1180
+ const TOOL_IMPLEMENTATIONS: Record<string, (input: string) => Promise<string>> = {
1181
+ async search(input: string): Promise<string> {
1182
+ return '[Search results for: ' + input + ']';
1183
+ },
1184
+ async calculate(input: string): Promise<string> {
1185
+ return '[Calculation result for: ' + input + ']';
1186
+ },
1187
+ };
1188
+
1189
+ // ============================================================
1190
+ // NODES
1191
+ // ============================================================
1192
+
1193
+ /**
1194
+ * ReAct loop: manages Think\u2192Act\u2192Observe iterations.
1195
+ * Accumulates messages and terminates when action is FINISH or max steps.
1196
+ *
1197
+ * @flowWeaver nodeType
1198
+ * @label ReAct Loop
1199
+ * @input execute [order:0] - Execute
1200
+ * @input task [order:1] - Task for the agent
1201
+ * @input [maxSteps] [order:2] - Maximum reasoning steps (default: 10)
1202
+ * @input success scope:step [order:0] - Iteration succeeded
1203
+ * @input failure scope:step [order:1] - Iteration failed
1204
+ * @input thought scope:step [order:2] - Agent's reasoning
1205
+ * @input action scope:step [order:3] - Action name
1206
+ * @input actionInput scope:step [order:4] - Action input / final answer
1207
+ * @input observation scope:step [order:5] - Tool observation
1208
+ * @output onSuccess [order:0] - On Success (finished)
1209
+ * @output onFailure [order:1] - On Failure
1210
+ * @output start scope:step [order:0] - Triggers iteration
1211
+ * @output messages scope:step [order:1] - Current messages for LLM
1212
+ * @output answer [order:2] - Final answer
1213
+ */
1214
+ async function reactLoop(
1215
+ execute: boolean,
1216
+ task: string,
1217
+ maxSteps: number = MAX_STEPS,
1218
+ step: (start: boolean, messages: LLMMessage[]) => Promise<{
1219
+ success: boolean;
1220
+ failure: boolean;
1221
+ thought: string;
1222
+ action: string;
1223
+ actionInput: string;
1224
+ observation: string;
1225
+ }>
1226
+ ): Promise<{ onSuccess: boolean; onFailure: boolean; answer: string }> {
1227
+ if (!execute) {
1228
+ return { onSuccess: false, onFailure: false, answer: '' };
1229
+ }
1230
+
1231
+ const messages: LLMMessage[] = [{ role: 'user', content: task }];
1232
+
1233
+ for (let i = 0; i < maxSteps; i++) {
1234
+ const result = await step(true, messages);
1235
+
1236
+ if (result.failure) {
1237
+ return { onSuccess: false, onFailure: true, answer: '' };
1238
+ }
1239
+
1240
+ // Append thought + action as assistant message
1241
+ messages.push({
1242
+ role: 'assistant',
1243
+ content: \`Thought: \${result.thought}\\nAction: \${result.action}\\nAction Input: \${result.actionInput}\`,
1244
+ });
1245
+
1246
+ // Check termination
1247
+ if (result.action.toUpperCase() === 'FINISH') {
1248
+ return { onSuccess: true, onFailure: false, answer: result.actionInput };
1249
+ }
1250
+
1251
+ // Append observation
1252
+ if (result.observation) {
1253
+ messages.push({ role: 'user', content: \`Observation: \${result.observation}\` });
1254
+ }
1255
+ }
1256
+
1257
+ return { onSuccess: true, onFailure: false, answer: 'Max steps reached' };
1258
+ }
1259
+
1260
+ /**
1261
+ * ReAct reasoning step: calls LLM and parses Thought/Action/ActionInput
1262
+ *
1263
+ * @flowWeaver nodeType
1264
+ * @label Think
1265
+ * @input execute [order:0] - Execute
1266
+ * @input messages [order:1] - Conversation history
1267
+ * @output onSuccess [order:0] - On Success
1268
+ * @output onFailure [order:1] - On Failure
1269
+ * @output thought [order:2] - Agent's reasoning
1270
+ * @output action [order:3] - Action to take (tool name or FINISH)
1271
+ * @output actionInput [order:4] - Input for action or final answer
1272
+ */
1273
+ async function think(
1274
+ execute: boolean,
1275
+ messages: LLMMessage[]
1276
+ ): Promise<{
1277
+ onSuccess: boolean;
1278
+ onFailure: boolean;
1279
+ thought: string;
1280
+ action: string;
1281
+ actionInput: string;
1282
+ }> {
1283
+ if (!execute) {
1284
+ return { onSuccess: false, onFailure: false, thought: '', action: '', actionInput: '' };
1285
+ }
1286
+
1287
+ try {
1288
+ const response = await llmProvider.chat(messages, { systemPrompt: REACT_PROMPT });
1289
+ const parsed = parseReactResponse(response.content ?? '');
1290
+
1291
+ return {
1292
+ onSuccess: true,
1293
+ onFailure: false,
1294
+ thought: parsed.thought,
1295
+ action: parsed.action,
1296
+ actionInput: parsed.actionInput,
1297
+ };
1298
+ } catch {
1299
+ return { onSuccess: false, onFailure: true, thought: '', action: '', actionInput: '' };
1300
+ }
1301
+ }
1302
+
1303
+ /**
1304
+ * Execute action and return observation
1305
+ *
1306
+ * @flowWeaver nodeType
1307
+ * @label Act
1308
+ * @input execute [order:0] - Execute
1309
+ * @input action [order:1] - Tool name to execute
1310
+ * @input actionInput [order:2] - Input for tool
1311
+ * @output onSuccess [order:0] - On Success
1312
+ * @output onFailure [order:1] - On Failure
1313
+ * @output observation [order:2] - Tool observation result
1314
+ */
1315
+ async function act(
1316
+ execute: boolean,
1317
+ action: string,
1318
+ actionInput: string
1319
+ ): Promise<{
1320
+ onSuccess: boolean;
1321
+ onFailure: boolean;
1322
+ observation: string;
1323
+ }> {
1324
+ if (!execute) {
1325
+ return { onSuccess: false, onFailure: false, observation: '' };
1326
+ }
1327
+
1328
+ const tool = TOOL_IMPLEMENTATIONS[action.toLowerCase()];
1329
+ if (!tool) {
1330
+ return {
1331
+ onSuccess: true,
1332
+ onFailure: false,
1333
+ observation: 'Unknown tool: ' + action,
1334
+ };
1335
+ }
1336
+
1337
+ try {
1338
+ const observation = await tool(actionInput);
1339
+ return { onSuccess: true, onFailure: false, observation };
1340
+ } catch (error) {
1341
+ return { onSuccess: false, onFailure: true, observation: '' };
1342
+ }
1343
+ }
1344
+
1345
+ // ============================================================
1346
+ // WORKFLOW
1347
+ // ============================================================
1348
+
1349
+ /**
1350
+ * ReAct Agent: iterative Thought\u2192Action\u2192Observation loop
1351
+ *
1352
+ * @flowWeaver workflow
1353
+ * @node loop reactLoop [color: "purple"] [icon: "psychology"]
1354
+ * @node thinking think loop.step [color: "blue"] [icon: "autoAwesome"]
1355
+ * @node acting act loop.step [color: "orange"] [icon: "bolt"]
1356
+ * @connect Start.execute -> loop.execute
1357
+ * @connect Start.task -> loop.task
1358
+ * @connect loop.start:step -> thinking.execute
1359
+ * @connect loop.messages:step -> thinking.messages
1360
+ * @connect thinking.onSuccess -> acting.execute
1361
+ * @connect thinking.action -> acting.action
1362
+ * @connect thinking.actionInput -> acting.actionInput
1363
+ * @connect thinking.thought -> loop.thought:step
1364
+ * @connect thinking.action -> loop.action:step
1365
+ * @connect thinking.actionInput -> loop.actionInput:step
1366
+ * @connect thinking.onFailure -> loop.failure:step
1367
+ * @connect acting.observation -> loop.observation:step
1368
+ * @connect acting.onSuccess -> loop.success:step
1369
+ * @connect acting.onFailure -> loop.failure:step
1370
+ * @connect loop.onSuccess -> Exit.onSuccess
1371
+ * @connect loop.onFailure -> Exit.onFailure
1372
+ * @connect loop.answer -> Exit.answer
1373
+ * @param execute [order:0] - Execute
1374
+ * @param task [order:1] - Task for the agent
1375
+ * @returns onSuccess [order:0] - On Success
1376
+ * @returns onFailure [order:1] - On Failure
1377
+ * @returns answer [order:2] - Final answer
1378
+ */
1379
+ export async function ${workflowName}(
1380
+ execute: boolean,
1381
+ params: { task: string }
1382
+ ): Promise<{
1383
+ onSuccess: boolean;
1384
+ onFailure: boolean;
1385
+ answer: string;
1386
+ }> {
1387
+ throw new Error('Compile with: fw compile <file>');
1388
+ }
1389
+ `.trim();
1390
+ }
1391
+ };
1392
+
1393
+ // src/cli/templates/workflows/ai-rag.ts
1394
+ var aiRagTemplate = {
1395
+ id: "ai-rag",
1396
+ name: "RAG Pipeline",
1397
+ description: "Retrieval-Augmented Generation for knowledge-based Q&A",
1398
+ category: "ai",
1399
+ configSchema: aiConfigSchema,
1400
+ generate: (opts) => {
1401
+ const { workflowName, config } = opts;
1402
+ const provider = config?.provider || "mock";
1403
+ const model = config?.model || "";
1404
+ const providerCode = provider === "mock" ? `
1405
+ // Mock provider for testing - replace with real provider
1406
+ ${LLM_MOCK_PROVIDER}
1407
+ ` : getProviderCode(provider, model);
1408
+ return `
1409
+ // ============================================================
1410
+ // LLM TYPES - Provider-agnostic interface
1411
+ // ============================================================
1412
+
1413
+ ${LLM_SIMPLE_TYPES}
1414
+
1415
+ ${providerCode}
1416
+
1417
+ // Document store (replace with vector DB like Pinecone, Weaviate, etc.)
1418
+ interface Document {
1419
+ id: string;
1420
+ content: string;
1421
+ metadata?: Record<string, unknown>;
1422
+ }
1423
+
1424
+ const documentStore: Document[] = [
1425
+ // TODO: Add your documents or connect to vector database
1426
+ { id: '1', content: 'Flow Weaver is a visual programming tool.' },
1427
+ { id: '2', content: 'It uses typed ports for data flow.' },
1428
+ ];
1429
+
1430
+ /**
1431
+ * Retrieves relevant documents for a query
1432
+ *
1433
+ * @flowWeaver nodeType
1434
+ * @label Retrieve
1435
+ * @input query [order:1] - Search query
1436
+ * @input [topK] [order:2] - Number of results (default 3)
1437
+ * @input execute [order:0] - Execute
1438
+ * @output documents [order:2] [hidden] - Retrieved documents
1439
+ * @output context [order:3] - Combined document text
1440
+ * @output onSuccess [order:0] - On Success
1441
+ * @output onFailure [order:1] - On Failure
1442
+ */
1443
+ async function retrieve(
1444
+ execute: boolean,
1445
+ query: string,
1446
+ topK?: number
1447
+ ): Promise<{
1448
+ onSuccess: boolean;
1449
+ onFailure: boolean;
1450
+ documents: Document[];
1451
+ context: string;
1452
+ }> {
1453
+ if (!execute) {
1454
+ return { onSuccess: false, onFailure: false, documents: [], context: '' };
1455
+ }
1456
+
1457
+ const k = topK ?? 3;
1458
+
1459
+ // TODO: Replace with actual vector similarity search
1460
+ // For now, simple keyword matching
1461
+ const queryLower = query.toLowerCase();
1462
+ const scored = documentStore
1463
+ .map((doc) => ({
1464
+ doc,
1465
+ score: doc.content.toLowerCase().includes(queryLower) ? 1 : 0,
1466
+ }))
1467
+ .filter((s) => s.score > 0)
1468
+ .slice(0, k)
1469
+ .map((s) => s.doc);
1470
+
1471
+ const context = scored.map((d) => d.content).join('\\n\\n');
1472
+
1473
+ return {
1474
+ onSuccess: true,
1475
+ onFailure: false,
1476
+ documents: scored,
1477
+ context,
1478
+ };
1479
+ }
1480
+
1481
+ /**
1482
+ * Generates answer using retrieved context
1483
+ *
1484
+ * @flowWeaver nodeType
1485
+ * @label Generate
1486
+ * @input question [order:1] - User question
1487
+ * @input context [order:2] - Retrieved context
1488
+ * @input execute [order:0] - Execute
1489
+ * @output answer [order:2] - Generated answer
1490
+ * @output sourcesUsed [order:3] - Number of sources used
1491
+ * @output onSuccess [order:0] - On Success
1492
+ * @output onFailure [order:1] - On Failure
1493
+ */
1494
+ async function generate(
1495
+ execute: boolean,
1496
+ question: string,
1497
+ context: string
1498
+ ): Promise<{
1499
+ onSuccess: boolean;
1500
+ onFailure: boolean;
1501
+ answer: string;
1502
+ sourcesUsed: number;
1503
+ }> {
1504
+ if (!execute) {
1505
+ return { onSuccess: false, onFailure: false, answer: '', sourcesUsed: 0 };
1506
+ }
1507
+
1508
+ const prompt = \`Answer the question based on the following context.
1509
+ If the context doesn't contain relevant information, say so.
1510
+
1511
+ Context:
1512
+ \${context}
1513
+
1514
+ Question: \${question}
1515
+
1516
+ Answer:\`;
1517
+
1518
+ const response = await llmProvider.chat([{ role: 'user', content: prompt }]);
1519
+ const sourcesUsed = context
1520
+ .split('\\n\\n')
1521
+ .filter((s) => s.trim()).length;
1522
+
1523
+ return {
1524
+ onSuccess: true,
1525
+ onFailure: false,
1526
+ answer: response.content ?? '',
1527
+ sourcesUsed,
1528
+ };
1529
+ }
1530
+
1531
+ /**
1532
+ * RAG Pipeline for knowledge-based Q&A
1533
+ *
1534
+ * @flowWeaver workflow
1535
+ * @node retriever retrieve [color: "teal"] [icon: "search"] [suppress: "UNUSED_OUTPUT_PORT", "DESIGN_ASYNC_NO_ERROR_PATH"]
1536
+ * @node generator generate [color: "purple"] [icon: "autoAwesome"]
1537
+ * @connect Start.execute -> retriever.execute
1538
+ * @connect Start.question -> retriever.query
1539
+ * @connect Start.topK -> retriever.topK
1540
+ * @connect Start.question -> generator.question
1541
+ * @connect retriever.context -> generator.context
1542
+ * @connect retriever.onSuccess -> generator.execute
1543
+ * @connect generator.answer -> Exit.answer
1544
+ * @connect generator.sourcesUsed -> Exit.sourcesUsed
1545
+ * @connect generator.onSuccess -> Exit.onSuccess
1546
+ * @connect generator.onFailure -> Exit.onFailure
1547
+ * @param execute [order:0] - Execute
1548
+ * @param question [order:1] - User's question
1549
+ * @param topK [order:2] - Number of documents to retrieve
1550
+ * @returns onSuccess [order:0] - On Success
1551
+ * @returns onFailure [order:1] - On Failure
1552
+ * @returns answer [order:2] - Generated answer
1553
+ * @returns sourcesUsed [order:3] - Number of sources used
1554
+ */
1555
+ export async function ${workflowName}(
1556
+ execute: boolean,
1557
+ params: { question: string; topK?: number }
1558
+ ): Promise<{
1559
+ onSuccess: boolean;
1560
+ onFailure: boolean;
1561
+ answer: string;
1562
+ sourcesUsed: number;
1563
+ }> {
1564
+ throw new Error('Compile with: fw compile <file>');
1565
+ }
1566
+ `.trim();
1567
+ }
1568
+ };
1569
+
1570
+ // src/cli/templates/workflows/ai-chat.ts
1571
+ var aiChatTemplate = {
1572
+ id: "ai-chat",
1573
+ name: "Stateful Chat",
1574
+ description: "Conversational AI with memory management",
1575
+ category: "ai",
1576
+ configSchema: aiConfigSchema,
1577
+ generate: (opts) => {
1578
+ const { workflowName, config } = opts;
1579
+ const provider = config?.provider || "mock";
1580
+ const model = config?.model || "";
1581
+ const providerCode = provider === "mock" ? `
1582
+ // Mock provider for testing - replace with real provider
1583
+ ${LLM_MOCK_PROVIDER}
1584
+ ` : getProviderCode(provider, model);
1585
+ return `
1586
+ // ============================================================
1587
+ // LLM TYPES - Provider-agnostic interface
1588
+ // ============================================================
1589
+
1590
+ ${LLM_SIMPLE_TYPES}
1591
+
1592
+ ${providerCode}
1593
+
1594
+ // Conversation memory store
1595
+ const conversations: Map<string, LLMMessage[]> = new Map();
1596
+
1597
+ const DEFAULT_SYSTEM_PROMPT = \`You are a helpful AI assistant.
1598
+ Be concise but friendly. Remember context from earlier in the conversation.\`;
1599
+
1600
+ /**
1601
+ * Manages conversation memory
1602
+ *
1603
+ * @flowWeaver nodeType
1604
+ * @label Memory
1605
+ * @input conversationId [order:1] - Conversation identifier
1606
+ * @input [newMessage] [order:2] - Message to add
1607
+ * @input [maxHistory=50] [order:3] - Max messages to retain
1608
+ * @input execute [order:0] - Execute
1609
+ * @output history [order:2] - Conversation history
1610
+ * @output onSuccess [order:0] - On Success
1611
+ * @output onFailure [order:1] - On Failure
1612
+ */
1613
+ function memory(
1614
+ execute: boolean,
1615
+ conversationId: string,
1616
+ newMessage?: LLMMessage,
1617
+ maxHistory?: number
1618
+ ): {
1619
+ onSuccess: boolean;
1620
+ onFailure: boolean;
1621
+ history: LLMMessage[];
1622
+ } {
1623
+ if (!execute) {
1624
+ return { onSuccess: false, onFailure: false, history: [] };
1625
+ }
1626
+
1627
+ if (!conversations.has(conversationId)) {
1628
+ conversations.set(conversationId, []);
1629
+ }
1630
+
1631
+ const history = conversations.get(conversationId)!;
1632
+
1633
+ if (newMessage) {
1634
+ history.push(newMessage);
1635
+ const max = maxHistory ?? 50;
1636
+ while (history.length > max) {
1637
+ history.shift();
1638
+ }
1639
+ }
1640
+
1641
+ return { onSuccess: true, onFailure: false, history: [...history] };
1642
+ }
1643
+
1644
+ /**
1645
+ * Generates chat response
1646
+ *
1647
+ * @flowWeaver nodeType
1648
+ * @label Chat
1649
+ * @input history [order:1] - Conversation history
1650
+ * @input [systemPrompt] [order:2] - System prompt
1651
+ * @input execute [order:0] - Execute
1652
+ * @output response [order:2] - Assistant response
1653
+ * @output responseMessage [order:3] - Response as LLMMessage
1654
+ * @output onSuccess [order:0] - On Success
1655
+ * @output onFailure [order:1] - On Failure
1656
+ */
1657
+ async function chat(
1658
+ execute: boolean,
1659
+ history: LLMMessage[],
1660
+ systemPrompt?: string
1661
+ ): Promise<{
1662
+ onSuccess: boolean;
1663
+ onFailure: boolean;
1664
+ response: string;
1665
+ responseMessage: LLMMessage;
1666
+ }> {
1667
+ if (!execute) {
1668
+ return {
1669
+ onSuccess: false,
1670
+ onFailure: false,
1671
+ response: '',
1672
+ responseMessage: { role: 'assistant', content: '' },
1673
+ };
1674
+ }
1675
+
1676
+ const response = await llmProvider.chat(history, {
1677
+ systemPrompt: systemPrompt ?? DEFAULT_SYSTEM_PROMPT,
1678
+ });
1679
+
1680
+ const content = response.content ?? '';
1681
+
1682
+ return {
1683
+ onSuccess: true,
1684
+ onFailure: false,
1685
+ response: content,
1686
+ responseMessage: { role: 'assistant', content },
1687
+ };
1688
+ }
1689
+
1690
+ /**
1691
+ * Stateful chat with conversation memory
1692
+ *
1693
+ * @flowWeaver workflow
1694
+ * @node mem memory [color: "teal"] [icon: "database"]
1695
+ * @node respond chat [color: "purple"] [icon: "campaign"] [suppress: "AGENT_LLM_NO_FALLBACK"]
1696
+ * @node saveMem memory [color: "teal"] [icon: "database"] [suppress: "UNUSED_OUTPUT_PORT"]
1697
+ * @connect Start.execute -> mem.execute
1698
+ * @connect Start.conversationId -> mem.conversationId
1699
+ * @connect Start.userMessage -> mem.newMessage
1700
+ * @connect mem.history -> respond.history
1701
+ * @connect mem.onSuccess -> respond.execute
1702
+ * @connect Start.conversationId -> saveMem.conversationId
1703
+ * @connect respond.responseMessage -> saveMem.newMessage
1704
+ * @connect respond.onSuccess -> saveMem.execute
1705
+ * @connect respond.onFailure -> Exit.onFailure
1706
+ * @connect respond.response -> Exit.response
1707
+ * @connect saveMem.onSuccess -> Exit.onSuccess
1708
+ * @param execute [order:0] - Execute
1709
+ * @param conversationId [order:1] - Unique conversation ID
1710
+ * @param userMessage [order:2] - User's message
1711
+ * @param systemPrompt [order:3] - System prompt (optional)
1712
+ * @returns onSuccess [order:0] - On Success
1713
+ * @returns onFailure [order:1] - On Failure
1714
+ * @returns response [order:2] - Assistant's response
1715
+ */
1716
+ export async function ${workflowName}(
1717
+ execute: boolean,
1718
+ params: { conversationId: string; userMessage: LLMMessage; systemPrompt?: string }
1719
+ ): Promise<{
1720
+ onSuccess: boolean;
1721
+ onFailure: boolean;
1722
+ response: string;
1723
+ }> {
1724
+ throw new Error('Compile with: fw compile <file>');
1725
+ }
1726
+ `.trim();
1727
+ }
1728
+ };
1729
+
1730
+ // src/cli/templates/workflows/aggregator.ts
1731
+ var aggregatorTemplate = {
1732
+ id: "aggregator",
1733
+ name: "Aggregator",
1734
+ description: "Combine multiple data sources into one output",
1735
+ category: "data-processing",
1736
+ generate: (opts) => {
1737
+ const { workflowName, async: isAsync } = opts;
1738
+ const asyncKeyword = isAsync ? "async " : "";
1739
+ const returnType = isAsync ? "Promise<{ onSuccess: boolean; onFailure: boolean; aggregated: any }>" : "{ onSuccess: boolean; onFailure: boolean; aggregated: any }";
1740
+ return `
1741
+ // Use @expression for most functions, normal mode only for error-with-data or void side-effects
1742
+
1743
+ /**
1744
+ * Fetches data from source A
1745
+ *
1746
+ * @flowWeaver nodeType
1747
+ * @expression
1748
+ * @label Fetch Source A
1749
+ * @input query [order:0] - Query parameters
1750
+ * @output data [order:0] - Data from source A
1751
+ */
1752
+ function fetchSourceA(query: any): { data: any } {
1753
+ // TODO: Fetch from source A
1754
+ return { data: { source: "A", items: [] } };
1755
+ }
1756
+
1757
+ /**
1758
+ * Fetches data from source B
1759
+ *
1760
+ * @flowWeaver nodeType
1761
+ * @expression
1762
+ * @label Fetch Source B
1763
+ * @input query [order:0] - Query parameters
1764
+ * @output data [order:0] - Data from source B
1765
+ */
1766
+ function fetchSourceB(query: any): { data: any } {
1767
+ // TODO: Fetch from source B
1768
+ return { data: { source: "B", items: [] } };
1769
+ }
1770
+
1771
+ /**
1772
+ * Combines data from multiple sources
1773
+ *
1774
+ * @flowWeaver nodeType
1775
+ * @expression
1776
+ * @label Combine Data
1777
+ * @input dataA [order:0] - Data from source A
1778
+ * @input dataB [order:1] - Data from source B
1779
+ * @output aggregated [order:0] - Combined data
1780
+ */
1781
+ function combineData(dataA: any, dataB: any): { aggregated: any } {
1782
+ // TODO: Implement aggregation logic
1783
+ return {
1784
+ aggregated: {
1785
+ sources: [dataA?.source, dataB?.source],
1786
+ totalItems: (dataA?.items?.length || 0) + (dataB?.items?.length || 0),
1787
+ items: [...(dataA?.items || []), ...(dataB?.items || [])],
1788
+ aggregatedAt: new Date().toISOString()
1789
+ }
1790
+ };
1791
+ }
1792
+
1793
+ /**
1794
+ * @flowWeaver workflow
1795
+ * @node sourceA fetchSourceA [color: "blue"] [icon: "download"]
1796
+ * @node sourceB fetchSourceB [color: "blue"] [icon: "download"]
1797
+ * @node combiner combineData [color: "purple"] [icon: "callMerge"]
1798
+ * @connect Start.execute -> sourceA.execute
1799
+ * @connect Start.execute -> sourceB.execute
1800
+ * @connect Start.query -> sourceA.query
1801
+ * @connect Start.query -> sourceB.query
1802
+ * @connect sourceA.onSuccess -> combiner.execute
1803
+ * @connect sourceA.data -> combiner.dataA
1804
+ * @connect sourceB.data -> combiner.dataB
1805
+ * @connect combiner.aggregated -> Exit.aggregated
1806
+ * @connect combiner.onSuccess -> Exit.onSuccess
1807
+ * @connect combiner.onFailure -> Exit.onFailure
1808
+ * @param execute [order:0] - Execute
1809
+ * @param query [order:1] - Query parameters for fetching
1810
+ * @returns onSuccess [order:0] - On Success
1811
+ * @returns onFailure [order:1] - On Failure
1812
+ * @returns aggregated [order:2] - Combined data from all sources
1813
+ */
1814
+ export ${asyncKeyword}function ${workflowName}(
1815
+ execute: boolean,
1816
+ params: { query: any }
1817
+ ): ${returnType} {
1818
+ throw new Error("Compile with: fw compile <file>");
1819
+ }
1820
+ `.trim();
1821
+ }
1822
+ };
1823
+
1824
+ // src/cli/templates/workflows/webhook.ts
1825
+ var webhookTemplate = {
1826
+ id: "webhook",
1827
+ name: "Webhook Handler",
1828
+ description: "HTTP-triggered workflow with request/response handling",
1829
+ category: "integration",
1830
+ generate: (opts) => {
1831
+ const { workflowName, async: isAsync } = opts;
1832
+ const asyncKeyword = isAsync ? "async " : "";
1833
+ const returnType = isAsync ? "Promise<{ onSuccess: boolean; onFailure: boolean; statusCode: number; body: any }>" : "{ onSuccess: boolean; onFailure: boolean; statusCode: number; body: any }";
1834
+ return `
1835
+ /**
1836
+ * Validates incoming webhook request
1837
+ *
1838
+ * @flowWeaver nodeType
1839
+ * @label Validate Request
1840
+ * @input headers [order:1] - Request headers
1841
+ * @input body [order:2] - Request body
1842
+ * @input execute [order:0] - Execute
1843
+ * @output isValid [order:2] - Whether request is valid
1844
+ * @output validatedData [order:3] - Validated request data
1845
+ * @output error [order:4] - Validation error message
1846
+ * @output onSuccess [order:0] - On Success
1847
+ * @output onFailure [order:1] - On Failure
1848
+ */
1849
+ function validateRequest(
1850
+ execute: boolean,
1851
+ headers: Record<string, string>,
1852
+ body: any
1853
+ ): { onSuccess: boolean; onFailure: boolean; isValid: boolean; validatedData: any; error: string } {
1854
+ if (!execute) {
1855
+ return { onSuccess: false, onFailure: false, isValid: false, validatedData: null, error: "" };
1856
+ }
1857
+
1858
+ // TODO: Add your validation logic
1859
+ // Example: Check API key, validate body schema, etc.
1860
+ const apiKey = headers["x-api-key"] || headers["authorization"];
1861
+
1862
+ if (!apiKey) {
1863
+ return { onSuccess: false, onFailure: true, isValid: false, validatedData: null, error: "Missing API key" };
1864
+ }
1865
+
1866
+ return { onSuccess: true, onFailure: false, isValid: true, validatedData: body, error: "" };
1867
+ }
1868
+
1869
+ /**
1870
+ * Processes the webhook payload
1871
+ *
1872
+ * @flowWeaver nodeType
1873
+ * @label Process Payload
1874
+ * @input data [order:1] - Validated payload data
1875
+ * @input execute [order:0] - Execute
1876
+ * @output result [order:2] - Processing result
1877
+ * @output onSuccess [order:0] - On Success
1878
+ * @output onFailure [order:1] - On Failure
1879
+ */
1880
+ function processPayload(
1881
+ execute: boolean,
1882
+ data: any
1883
+ ): { onSuccess: boolean; onFailure: boolean; result: any } {
1884
+ if (!execute) {
1885
+ return { onSuccess: false, onFailure: false, result: null };
1886
+ }
1887
+
1888
+ // TODO: Add your business logic
1889
+ const result = {
1890
+ processed: true,
1891
+ timestamp: new Date().toISOString(),
1892
+ data
1893
+ };
1894
+
1895
+ return { onSuccess: true, onFailure: false, result };
1896
+ }
1897
+
1898
+ /**
1899
+ * Formats the HTTP response
1900
+ *
1901
+ * @flowWeaver nodeType
1902
+ * @label Format Response
1903
+ * @input result [order:1] - Processing result
1904
+ * @input error [order:2] - Error message if any
1905
+ * @input isSuccess [order:3] - Whether processing succeeded
1906
+ * @input execute [order:0] - Execute
1907
+ * @output statusCode [order:2] - HTTP status code
1908
+ * @output body [order:3] - Response body
1909
+ * @output onSuccess [order:0] - On Success
1910
+ * @output onFailure [order:1] - On Failure
1911
+ */
1912
+ function formatResponse(
1913
+ execute: boolean,
1914
+ result: any,
1915
+ error: string,
1916
+ isSuccess: boolean
1917
+ ): { onSuccess: boolean; onFailure: boolean; statusCode: number; body: any } {
1918
+ if (!execute) {
1919
+ return { onSuccess: false, onFailure: false, statusCode: 0, body: null };
1920
+ }
1921
+
1922
+ if (isSuccess) {
1923
+ return {
1924
+ onSuccess: true,
1925
+ onFailure: false,
1926
+ statusCode: 200,
1927
+ body: { success: true, data: result }
1928
+ };
1929
+ } else {
1930
+ return {
1931
+ onSuccess: true,
1932
+ onFailure: false,
1933
+ statusCode: 400,
1934
+ body: { success: false, error: error || "Processing failed" }
1935
+ };
1936
+ }
1937
+ }
1938
+
1939
+ /**
1940
+ * @flowWeaver workflow
1941
+ * @node validator validateRequest [color: "green"] [icon: "verified"]
1942
+ * @node processor processPayload [color: "blue"] [icon: "settings"]
1943
+ * @node responder formatResponse [color: "cyan"] [icon: "send"]
1944
+ * @connect Start.execute -> validator.execute
1945
+ * @connect Start.headers -> validator.headers
1946
+ * @connect Start.body -> validator.body
1947
+ * @connect validator.onSuccess -> processor.execute
1948
+ * @connect validator.validatedData -> processor.data
1949
+ * @connect validator.error -> responder.error
1950
+ * @connect processor.onSuccess -> responder.execute
1951
+ * @connect processor.result -> responder.result
1952
+ * @connect validator.isValid -> responder.isSuccess
1953
+ * @connect responder.statusCode -> Exit.statusCode
1954
+ * @connect responder.body -> Exit.body
1955
+ * @connect responder.onSuccess -> Exit.onSuccess
1956
+ * @connect responder.onFailure -> Exit.onFailure
1957
+ * @param execute [order:0] - Execute
1958
+ * @param headers [order:1] - HTTP request headers
1959
+ * @param body [order:2] - HTTP request body
1960
+ * @returns onSuccess [order:0] - On Success
1961
+ * @returns onFailure [order:1] - On Failure
1962
+ * @returns statusCode [order:2] - HTTP response status code
1963
+ * @returns body [order:3] - HTTP response body
1964
+ */
1965
+ export ${asyncKeyword}function ${workflowName}(
1966
+ execute: boolean,
1967
+ params: { headers: Record<string, string>; body: any }
1968
+ ): ${returnType} {
1969
+ throw new Error("Compile with: fw compile <file>");
1970
+ }
1971
+ `.trim();
1972
+ }
1973
+ };
1974
+
1975
+ // src/cli/templates/workflows/error-handler.ts
1976
+ var errorHandlerTemplate = {
1977
+ id: "error-handler",
1978
+ name: "Error Handler",
1979
+ description: "Try/catch/retry pattern with error recovery",
1980
+ category: "utility",
1981
+ generate: (opts) => {
1982
+ const { workflowName, async: isAsync } = opts;
1983
+ const asyncKeyword = isAsync ? "async " : "";
1984
+ const returnType = isAsync ? "Promise<{ onSuccess: boolean; onFailure: boolean; result: any; attempts: number; lastError?: string }>" : "{ onSuccess: boolean; onFailure: boolean; result: any; attempts: number; lastError?: string }";
1985
+ return `
1986
+ /**
1987
+ * Retry loop that orchestrates operation attempts
1988
+ * Uses scoped ports to handle retry iteration internally
1989
+ *
1990
+ * @flowWeaver nodeType
1991
+ * @label Retry Loop
1992
+ * @input data [order:1] - Input data to process
1993
+ * @input maxRetries [order:2] - Maximum retry attempts
1994
+ * @input success scope:attempt [order:0] - From operation onSuccess
1995
+ * @input failure scope:attempt [order:1] - From operation onFailure
1996
+ * @input result scope:attempt [order:2] - Operation result
1997
+ * @input error scope:attempt [order:3] - Error from operation
1998
+ * @input execute [order:0] - Execute
1999
+ * @output start scope:attempt [order:0] - Triggers attempt
2000
+ * @output attemptData scope:attempt [order:1] - Data for this attempt
2001
+ * @output attemptNum scope:attempt [order:2] - Current attempt number
2002
+ * @output finalResult [order:2] - Final result
2003
+ * @output attempts [order:3] - Total attempts made
2004
+ * @output lastError [order:4] - Last error if failed
2005
+ * @output onSuccess [order:0] - On Success
2006
+ * @output onFailure [order:1] - On Failure
2007
+ */
2008
+ function retryLoop(
2009
+ execute: boolean,
2010
+ data: any,
2011
+ maxRetries: number,
2012
+ attempt: (start: boolean, attemptData: any, attemptNum: number) => {
2013
+ success: boolean;
2014
+ failure: boolean;
2015
+ result: any;
2016
+ error: string;
2017
+ }
2018
+ ): { onSuccess: boolean; onFailure: boolean; finalResult: any; attempts: number; lastError: string } {
2019
+ if (!execute) {
2020
+ return { onSuccess: false, onFailure: false, finalResult: null, attempts: 0, lastError: '' };
2021
+ }
2022
+
2023
+ let lastError = '';
2024
+ for (let attemptNum = 1; attemptNum <= maxRetries; attemptNum++) {
2025
+ const result = attempt(true, data, attemptNum);
2026
+
2027
+ if (result.success) {
2028
+ return { onSuccess: true, onFailure: false, finalResult: result.result, attempts: attemptNum, lastError: '' };
2029
+ }
2030
+
2031
+ lastError = result.error;
2032
+ console.log(\`[Retry] Attempt \${attemptNum} failed: \${lastError}. \${attemptNum < maxRetries ? 'Retrying...' : 'Max retries reached.'}\`);
2033
+ }
2034
+
2035
+ return { onSuccess: false, onFailure: true, finalResult: null, attempts: maxRetries, lastError };
2036
+ }
2037
+
2038
+ /**
2039
+ * Attempts an operation that might fail
2040
+ *
2041
+ * @flowWeaver nodeType
2042
+ * @label Try Operation
2043
+ * @input data [order:1] - Input data
2044
+ * @input attempt [order:2] - Current attempt number
2045
+ * @input execute [order:0] - Execute
2046
+ * @output result [order:2] - Operation result
2047
+ * @output error [order:3] - Error message if failed
2048
+ * @output onSuccess [order:0] - On Success
2049
+ * @output onFailure [order:1] - On Failure
2050
+ */
2051
+ function tryOperation(
2052
+ execute: boolean,
2053
+ data: any,
2054
+ attempt: number
2055
+ ): { onSuccess: boolean; onFailure: boolean; result: any; error: string } {
2056
+ if (!execute) {
2057
+ return { onSuccess: false, onFailure: false, result: null, error: '' };
2058
+ }
2059
+
2060
+ try {
2061
+ // TODO: Replace with your operation that might fail
2062
+ // This is a placeholder that randomly fails for demonstration
2063
+ if (Math.random() < 0.3) {
2064
+ throw new Error('Simulated failure');
2065
+ }
2066
+
2067
+ const result = { processed: data, attempt };
2068
+ return { onSuccess: true, onFailure: false, result, error: '' };
2069
+ } catch (err) {
2070
+ const error = err instanceof Error ? err.message : String(err);
2071
+ return { onSuccess: false, onFailure: true, result: null, error };
2072
+ }
2073
+ }
2074
+
2075
+ /**
2076
+ * @flowWeaver workflow
2077
+ * @node loop retryLoop [color: "orange"] [icon: "refresh"]
2078
+ * @node tryOp tryOperation loop.attempt [color: "blue"] [icon: "playArrow"]
2079
+ * @connect Start.execute -> loop.execute
2080
+ * @connect Start.data -> loop.data
2081
+ * @connect Start.maxRetries -> loop.maxRetries
2082
+ * @connect loop.start:attempt -> tryOp.execute
2083
+ * @connect loop.attemptData:attempt -> tryOp.data
2084
+ * @connect loop.attemptNum:attempt -> tryOp.attempt
2085
+ * @connect tryOp.result -> loop.result:attempt
2086
+ * @connect tryOp.error -> loop.error:attempt
2087
+ * @connect tryOp.onSuccess -> loop.success:attempt
2088
+ * @connect tryOp.onFailure -> loop.failure:attempt
2089
+ * @connect loop.finalResult -> Exit.result
2090
+ * @connect loop.attempts -> Exit.attempts
2091
+ * @connect loop.lastError -> Exit.lastError
2092
+ * @connect loop.onSuccess -> Exit.onSuccess
2093
+ * @connect loop.onFailure -> Exit.onFailure
2094
+ * @param execute [order:0] - Execute
2095
+ * @param data [order:1] - Input data to process
2096
+ * @param [maxRetries=3] [order:2] - Maximum retry attempts
2097
+ * @returns onSuccess [order:0] - Operation succeeded
2098
+ * @returns onFailure [order:1] - All retries exhausted
2099
+ * @returns result [order:2] - Operation result
2100
+ * @returns attempts [order:3] - Number of attempts made
2101
+ * @returns lastError [order:4] - Last error message if failed
2102
+ */
2103
+ export ${asyncKeyword}function ${workflowName}(
2104
+ execute: boolean,
2105
+ params: { data: any; maxRetries?: number }
2106
+ ): ${returnType} {
2107
+ throw new Error("Compile with: fw compile <file>");
2108
+ }
2109
+ `.trim();
2110
+ }
2111
+ };
2112
+
2113
+ // src/cli/templates/workflows/approval.ts
2114
+ var configSchema2 = {
2115
+ input: {
2116
+ type: "string",
2117
+ label: "Input Port Name",
2118
+ description: "Name of the parameter that carries what needs approval",
2119
+ default: "request",
2120
+ placeholder: "request"
2121
+ },
2122
+ output: {
2123
+ type: "string",
2124
+ label: "Output Port Name",
2125
+ description: "Name of the return value",
2126
+ default: "outcome",
2127
+ placeholder: "outcome"
2128
+ }
2129
+ };
2130
+ var approvalTemplate = {
2131
+ id: "approval",
2132
+ name: "Approval",
2133
+ description: "Prepare a request, pause for a person to approve it, then carry it out",
2134
+ category: "automation",
2135
+ configSchema: configSchema2,
2136
+ generate: (opts) => {
2137
+ const { workflowName, config } = opts;
2138
+ const input = config?.input || "request";
2139
+ const output = config?.output || "outcome";
2140
+ return `
2141
+ /**
2142
+ * Summarises the ${input} for the person who will decide.
2143
+ *
2144
+ * @flowWeaver nodeType
2145
+ * @expression
2146
+ * @label Prepare
2147
+ * @input ${input} - What needs approval
2148
+ * @output summary - One line for the approver
2149
+ * @output ${input} - The same, passed on
2150
+ */
2151
+ function prepare${cap(input)}(${input}: any): { summary: string; ${input}: any } {
2152
+ // TODO: say what is being asked, in one line
2153
+ return { summary: typeof ${input} === 'string' ? ${input} : JSON.stringify(${input}), ${input} };
2154
+ }
2155
+
2156
+ /**
2157
+ * A person approves or refuses. The run pauses here and resumes with the
2158
+ * answer: the approver's note on onSuccess, or a refusal along onFailure.
2159
+ * The body never runs. The coordinator substitutes the answer.
2160
+ *
2161
+ * @flowWeaver nodeType
2162
+ * @durableGate approval
2163
+ * @label Approve
2164
+ * @input summary - What the approver sees
2165
+ * @output note - What the approver said
2166
+ */
2167
+ async function approve(
2168
+ execute: boolean,
2169
+ summary: string
2170
+ ): Promise<{ onSuccess: boolean; onFailure: boolean; note: string }> {
2171
+ throw new Error(\`durable gate: never executes (\${execute}:\${summary})\`);
2172
+ }
2173
+
2174
+ /**
2175
+ * Carries out the approved ${input}.
2176
+ *
2177
+ * @flowWeaver nodeType
2178
+ * @expression
2179
+ * @label Apply
2180
+ * @input ${input} - The approved ${input}, from Prepare
2181
+ * @input note - The approver's note
2182
+ * @output ${output} - What happened
2183
+ */
2184
+ function apply${cap(input)}(${input}: any, note: string): { ${output}: string } {
2185
+ // TODO: do the thing
2186
+ return { ${output}: \`applied \${JSON.stringify(${input})} -- \${note}\` };
2187
+ }
2188
+
2189
+ /**
2190
+ * @flowWeaver workflow
2191
+ * @node prepare prepare${cap(input)} [color: "blue"] [icon: "description"]
2192
+ * @node approval approve [color: "purple"] [icon: "how_to_reg"]
2193
+ * @node apply apply${cap(input)} [color: "green"] [icon: "task_alt"]
2194
+ * @path Start -> prepare -> approval -> apply -> Exit
2195
+ * @path approval:fail -> Exit
2196
+ * @param ${input} - What needs approval
2197
+ * @returns ${output} - What happened
2198
+ */
2199
+ export async function ${workflowName}(
2200
+ execute: boolean,
2201
+ params: { ${input}: any }
2202
+ ): Promise<{ onSuccess: boolean, onFailure: boolean, ${output}: string }> {
2203
+ throw new Error("Compile with: fw compile <file>");
2204
+ }
2205
+ `.trim();
2206
+ }
2207
+ };
2208
+ var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
2209
+
2210
+ // src/cli/templates/nodes/validator.ts
2211
+ var validatorNodeTemplate = {
2212
+ id: "validator",
2213
+ name: "Validator",
2214
+ description: "Input validation with success/failure routing",
2215
+ category: "validation",
2216
+ generate: (name) => {
2217
+ const pascalName = toPascalCase(name);
2218
+ return `
2219
+ /**
2220
+ * Validates input data against rules
2221
+ *
2222
+ * @flowWeaver nodeType
2223
+ * @label ${pascalName}
2224
+ * @color green
2225
+ * @icon rule
2226
+ * @input data [order:1] - Data to validate
2227
+ * @input execute [order:0] - Execute
2228
+ * @output isValid [order:2] - Whether data is valid
2229
+ * @output validData [order:3] - Validated data (if valid)
2230
+ * @output errors [order:4] - Validation errors (if invalid)
2231
+ * @output onSuccess [order:0] - Validation passed
2232
+ * @output onFailure [order:1] - Validation failed
2233
+ */
2234
+ function ${name}(
2235
+ execute: boolean,
2236
+ data: any
2237
+ ): { onSuccess: boolean; onFailure: boolean; isValid: boolean; validData: any; errors: string[] } {
2238
+ if (!execute) {
2239
+ return { onSuccess: false, onFailure: false, isValid: false, validData: null, errors: [] };
2240
+ }
2241
+
2242
+ const errors: string[] = [];
2243
+
2244
+ // TODO: Add your validation rules
2245
+ // Example validations:
2246
+ if (data === null || data === undefined) {
2247
+ errors.push("Data is required");
2248
+ }
2249
+
2250
+ // if (typeof data.email === 'string' && !data.email.includes('@')) {
2251
+ // errors.push("Invalid email format");
2252
+ // }
2253
+
2254
+ // if (typeof data.age === 'number' && (data.age < 0 || data.age > 150)) {
2255
+ // errors.push("Age must be between 0 and 150");
2256
+ // }
2257
+
2258
+ if (errors.length > 0) {
2259
+ return { onSuccess: false, onFailure: true, isValid: false, validData: null, errors };
2260
+ }
2261
+
2262
+ return { onSuccess: true, onFailure: false, isValid: true, validData: data, errors: [] };
2263
+ }
2264
+ `.trim();
2265
+ }
2266
+ };
2267
+
2268
+ // src/cli/templates/nodes/transformer.ts
2269
+ var transformerNodeTemplate = {
2270
+ id: "transformer",
2271
+ name: "Transformer",
2272
+ description: "Data transformation and mapping",
2273
+ category: "data",
2274
+ generate: (name) => {
2275
+ const pascalName = toPascalCase(name);
2276
+ return `
2277
+ /**
2278
+ * Transforms input data into a new shape
2279
+ *
2280
+ * @flowWeaver nodeType
2281
+ * @label ${pascalName}
2282
+ * @color pink
2283
+ * @icon changeCircle
2284
+ * @input data [order:1] - Input data to transform
2285
+ * @input execute [order:0] - Execute
2286
+ * @output result [order:2] - Transformed data
2287
+ * @output onSuccess [order:0] - On Success
2288
+ * @output onFailure [order:1] - On Failure
2289
+ */
2290
+ function ${name}(
2291
+ execute: boolean,
2292
+ data: any
2293
+ ): { onSuccess: boolean; onFailure: boolean; result: any } {
2294
+ if (!execute) {
2295
+ return { onSuccess: false, onFailure: false, result: null };
2296
+ }
2297
+
2298
+ try {
2299
+ // TODO: Implement your transformation logic
2300
+ // Examples:
2301
+
2302
+ // Map array items
2303
+ // const result = data.map(item => ({ ...item, processed: true }));
2304
+
2305
+ // Reshape object
2306
+ // const result = {
2307
+ // id: data.userId,
2308
+ // fullName: \`\${data.firstName} \${data.lastName}\`,
2309
+ // email: data.contactEmail
2310
+ // };
2311
+
2312
+ // Filter and transform
2313
+ // const result = data
2314
+ // .filter(item => item.active)
2315
+ // .map(item => item.name);
2316
+
2317
+ const result = {
2318
+ ...data,
2319
+ transformedAt: new Date().toISOString()
2320
+ };
2321
+
2322
+ return { onSuccess: true, onFailure: false, result };
2323
+ } catch (err) {
2324
+ console.error("[${pascalName}] Transform error:", err);
2325
+ return { onSuccess: false, onFailure: true, result: null };
2326
+ }
2327
+ }
2328
+ `.trim();
2329
+ }
2330
+ };
2331
+
2332
+ // src/cli/templates/nodes/http.ts
2333
+ var httpNodeTemplate = {
2334
+ id: "http",
2335
+ name: "HTTP Request",
2336
+ description: "Make HTTP requests to external APIs",
2337
+ category: "integration",
2338
+ generate: (name) => {
2339
+ const pascalName = toPascalCase(name);
2340
+ return `
2341
+ /**
2342
+ * Makes an HTTP request
2343
+ *
2344
+ * @flowWeaver nodeType
2345
+ * @label ${pascalName}
2346
+ * @color blue
2347
+ * @icon api
2348
+ * @input url [order:1] - Request URL
2349
+ * @input method [order:2] - HTTP method (GET, POST, PUT, DELETE)
2350
+ * @input headers [order:3] - Request headers
2351
+ * @input body [order:4] - Request body
2352
+ * @input execute [order:0] - Execute
2353
+ * @output response [order:2] - Response data
2354
+ * @output statusCode [order:3] - HTTP status code
2355
+ * @output onSuccess [order:0] - On Success
2356
+ * @output onFailure [order:1] - On Failure
2357
+ */
2358
+ async function ${name}(
2359
+ execute: boolean,
2360
+ url: string,
2361
+ method: "GET" | "POST" | "PUT" | "DELETE",
2362
+ headers: Record<string, string>,
2363
+ body: any
2364
+ ): Promise<{ onSuccess: boolean; onFailure: boolean; response: any; statusCode: number }> {
2365
+ if (!execute) {
2366
+ return { onSuccess: false, onFailure: false, response: null, statusCode: 0 };
2367
+ }
2368
+
2369
+ try {
2370
+ const options: RequestInit = {
2371
+ method,
2372
+ headers: {
2373
+ "Content-Type": "application/json",
2374
+ ...headers
2375
+ }
2376
+ };
2377
+
2378
+ if (method !== "GET" && body) {
2379
+ options.body = JSON.stringify(body);
2380
+ }
2381
+
2382
+ const res = await fetch(url, options);
2383
+ const statusCode = res.status;
2384
+
2385
+ let response;
2386
+ const contentType = res.headers.get("content-type");
2387
+ if (contentType?.includes("application/json")) {
2388
+ response = await res.json();
2389
+ } else {
2390
+ response = await res.text();
2391
+ }
2392
+
2393
+ if (!res.ok) {
2394
+ console.error("[${pascalName}] HTTP error:", statusCode, response);
2395
+ return { onSuccess: false, onFailure: true, response, statusCode };
2396
+ }
2397
+
2398
+ return { onSuccess: true, onFailure: false, response, statusCode };
2399
+ } catch (err) {
2400
+ console.error("[${pascalName}] Request failed:", err);
2401
+ return { onSuccess: false, onFailure: true, response: null, statusCode: 0 };
2402
+ }
2403
+ }
2404
+ `.trim();
2405
+ }
2406
+ };
2407
+
2408
+ // src/cli/templates/nodes/aggregator.ts
2409
+ var aggregatorNodeTemplate = {
2410
+ id: "aggregator",
2411
+ name: "Aggregator",
2412
+ description: "Combine multiple inputs into a single output",
2413
+ category: "data",
2414
+ generate: (name) => {
2415
+ const pascalName = toPascalCase(name);
2416
+ return `
2417
+ /**
2418
+ * Combines multiple inputs into a single output
2419
+ *
2420
+ * @flowWeaver nodeType
2421
+ * @label ${pascalName}
2422
+ * @color orange
2423
+ * @icon callMerge
2424
+ * @input inputA [order:1] - First input
2425
+ * @input inputB [order:2] - Second input
2426
+ * @input inputC [order:3] - Third input (optional)
2427
+ * @input execute [order:0] - Execute
2428
+ * @output combined [order:2] - Combined result
2429
+ * @output count [order:3] - Number of non-null inputs combined
2430
+ * @output onSuccess [order:0] - On Success
2431
+ * @output onFailure [order:1] - On Failure
2432
+ */
2433
+ function ${name}(
2434
+ execute: boolean,
2435
+ inputA: any,
2436
+ inputB: any,
2437
+ inputC: any
2438
+ ): { onSuccess: boolean; onFailure: boolean; combined: any; count: number } {
2439
+ if (!execute) {
2440
+ return { onSuccess: false, onFailure: false, combined: null, count: 0 };
2441
+ }
2442
+
2443
+ // TODO: Customize aggregation logic based on your data types
2444
+ const inputs = [inputA, inputB, inputC].filter(x => x !== null && x !== undefined);
2445
+ const count = inputs.length;
2446
+
2447
+ // Default: merge arrays or objects, or collect into array
2448
+ let combined: any;
2449
+
2450
+ if (inputs.every(Array.isArray)) {
2451
+ // Merge arrays
2452
+ combined = inputs.flat();
2453
+ } else if (inputs.every(x => typeof x === "object" && x !== null && !Array.isArray(x))) {
2454
+ // Merge objects
2455
+ combined = Object.assign({}, ...inputs);
2456
+ } else {
2457
+ // Collect as array
2458
+ combined = inputs;
2459
+ }
2460
+
2461
+ return { onSuccess: true, onFailure: false, combined, count };
2462
+ }
2463
+ `.trim();
2464
+ }
2465
+ };
2466
+
2467
+ // src/cli/templates/nodes/llm-call.ts
2468
+ var llmCallNodeTemplate = {
2469
+ id: "llm-call",
2470
+ name: "LLM Call",
2471
+ description: "Provider-agnostic LLM API call with tool support",
2472
+ category: "ai",
2473
+ generate: (name) => {
2474
+ const funcName = name || "llmCall";
2475
+ return `
2476
+ // LLM Types
2477
+ interface LLMMessage { role: 'system' | 'user' | 'assistant' | 'tool'; content: string; toolCallId?: string; }
2478
+ interface LLMTool { name: string; description: string; parameters: { type: 'object'; properties: Record<string, { type: string; description?: string }>; required?: string[] }; }
2479
+ interface LLMToolCall { id: string; name: string; arguments: Record<string, unknown>; }
2480
+ interface LLMResponse { content: string | null; toolCalls: LLMToolCall[]; finishReason: string; }
2481
+ interface LLMProvider { chat(messages: LLMMessage[], options?: { tools?: LLMTool[]; temperature?: number }): Promise<LLMResponse>; }
2482
+
2483
+ // Mock provider - replace with real provider (OpenAI, Anthropic, etc.)
2484
+ const createMockProvider = (): LLMProvider => ({
2485
+ async chat(messages, options) {
2486
+ const lastMsg = messages[messages.length - 1];
2487
+ if (options?.tools?.length && lastMsg.content.toLowerCase().includes('search')) {
2488
+ return { content: null, toolCalls: [{ id: \`call_\${Date.now()}\`, name: 'search', arguments: { query: lastMsg.content } }], finishReason: 'tool_calls' };
2489
+ }
2490
+ return { content: \`[Mock: \${lastMsg.content.slice(0, 40)}...]\`, toolCalls: [], finishReason: 'stop' };
2491
+ },
2492
+ });
2493
+
2494
+ const llmProvider: LLMProvider = createMockProvider();
2495
+
2496
+ /**
2497
+ * Calls an LLM with messages and optional tools
2498
+ *
2499
+ * @flowWeaver nodeType
2500
+ * @label ${funcName}
2501
+ * @color purple
2502
+ * @icon psychology
2503
+ * @input messages [order:1] - Conversation messages
2504
+ * @input tools [order:2] - Available tools/functions (optional)
2505
+ * @input systemPrompt [order:3] - System prompt (optional)
2506
+ * @input temperature [order:4] - Temperature 0-1 (optional)
2507
+ * @input execute [order:0] - Execute
2508
+ * @output content [order:2] - Text response (null if tool call)
2509
+ * @output toolCalls [order:3] - Tool calls requested by LLM
2510
+ * @output hasToolCalls [order:4] - Whether LLM wants to call tools
2511
+ * @output finishReason [order:5] - Why generation stopped
2512
+ * @output onSuccess [order:0] - On Success
2513
+ * @output onFailure [order:1] - On Failure
2514
+ */
2515
+ async function ${funcName}(
2516
+ execute: boolean,
2517
+ messages: LLMMessage[],
2518
+ tools?: LLMTool[],
2519
+ systemPrompt?: string,
2520
+ temperature?: number
2521
+ ): Promise<{
2522
+ onSuccess: boolean;
2523
+ onFailure: boolean;
2524
+ content: string | null;
2525
+ toolCalls: LLMToolCall[];
2526
+ hasToolCalls: boolean;
2527
+ finishReason: string;
2528
+ }> {
2529
+ if (!execute) {
2530
+ return {
2531
+ onSuccess: false,
2532
+ onFailure: false,
2533
+ content: null,
2534
+ toolCalls: [],
2535
+ hasToolCalls: false,
2536
+ finishReason: 'skipped'
2537
+ };
2538
+ }
2539
+
2540
+ try {
2541
+ const allMessages: LLMMessage[] = systemPrompt
2542
+ ? [{ role: 'system', content: systemPrompt }, ...messages]
2543
+ : messages;
2544
+
2545
+ const response = await llmProvider.chat(allMessages, {
2546
+ tools,
2547
+ temperature,
2548
+ });
2549
+
2550
+ return {
2551
+ onSuccess: true,
2552
+ onFailure: false,
2553
+ content: response.content,
2554
+ toolCalls: response.toolCalls,
2555
+ hasToolCalls: response.toolCalls.length > 0,
2556
+ finishReason: response.finishReason
2557
+ };
2558
+ } catch (error) {
2559
+ console.error('LLM call failed:', error);
2560
+ return {
2561
+ onSuccess: false,
2562
+ onFailure: true,
2563
+ content: null,
2564
+ toolCalls: [],
2565
+ hasToolCalls: false,
2566
+ finishReason: 'error'
2567
+ };
2568
+ }
2569
+ }
2570
+ `.trim();
2571
+ }
2572
+ };
2573
+
2574
+ // src/cli/templates/nodes/tool-executor.ts
2575
+ var toolExecutorNodeTemplate = {
2576
+ id: "tool-executor",
2577
+ name: "Tool Executor",
2578
+ description: "Executes tool calls from LLM response",
2579
+ category: "ai",
2580
+ generate: (name) => {
2581
+ const funcName = name || "executeTool";
2582
+ return `
2583
+ // LLM Types
2584
+ interface LLMToolCall { id: string; name: string; arguments: Record<string, unknown>; }
2585
+ interface LLMMessage { role: 'system' | 'user' | 'assistant' | 'tool'; content: string; toolCallId?: string; }
2586
+
2587
+ // Register your tools here
2588
+ type ToolFunction = (args: Record<string, unknown>) => Promise<unknown>;
2589
+ const toolRegistry: Record<string, ToolFunction> = {
2590
+ // Example tools:
2591
+ // 'search': async (args) => {
2592
+ // const query = String(args.query || '');
2593
+ // return await searchDatabase(query);
2594
+ // },
2595
+ // 'get_weather': async (args) => {
2596
+ // const city = String(args.city || '');
2597
+ // const response = await fetch(\`https://api.weather.example/v1/\${encodeURIComponent(city)}\`);
2598
+ // return response.json();
2599
+ // },
2600
+ };
2601
+
2602
+ /**
2603
+ * Executes a single tool call and returns result as message
2604
+ *
2605
+ * @flowWeaver nodeType
2606
+ * @label ${funcName}
2607
+ * @color cyan
2608
+ * @icon build
2609
+ * @input toolCall [order:1] - Tool call to execute
2610
+ * @input execute [order:0] - Execute
2611
+ * @output result [order:2] - Tool execution result
2612
+ * @output resultMessage [order:3] - Result formatted as LLM message
2613
+ * @output toolName [order:4] - Name of executed tool
2614
+ * @output onSuccess [order:0] - On Success
2615
+ * @output onFailure [order:1] - On Failure
2616
+ */
2617
+ async function ${funcName}(
2618
+ execute: boolean,
2619
+ toolCall: LLMToolCall
2620
+ ): Promise<{
2621
+ onSuccess: boolean;
2622
+ onFailure: boolean;
2623
+ result: unknown;
2624
+ resultMessage: LLMMessage;
2625
+ toolName: string;
2626
+ }> {
2627
+ if (!execute) {
2628
+ return {
2629
+ onSuccess: false,
2630
+ onFailure: false,
2631
+ result: null,
2632
+ resultMessage: { role: 'tool', content: '', toolCallId: '' },
2633
+ toolName: ''
2634
+ };
2635
+ }
2636
+
2637
+ const tool = toolRegistry[toolCall.name];
2638
+ if (!tool) {
2639
+ return {
2640
+ onSuccess: false,
2641
+ onFailure: true,
2642
+ result: null,
2643
+ resultMessage: {
2644
+ role: 'tool',
2645
+ content: JSON.stringify({ error: \`Unknown tool: \${toolCall.name}\` }),
2646
+ toolCallId: toolCall.id
2647
+ },
2648
+ toolName: toolCall.name
2649
+ };
2650
+ }
2651
+
2652
+ try {
2653
+ const result = await tool(toolCall.arguments);
2654
+ return {
2655
+ onSuccess: true,
2656
+ onFailure: false,
2657
+ result,
2658
+ resultMessage: {
2659
+ role: 'tool',
2660
+ content: JSON.stringify(result),
2661
+ toolCallId: toolCall.id
2662
+ },
2663
+ toolName: toolCall.name
2664
+ };
2665
+ } catch (error) {
2666
+ return {
2667
+ onSuccess: false,
2668
+ onFailure: true,
2669
+ result: null,
2670
+ resultMessage: {
2671
+ role: 'tool',
2672
+ content: JSON.stringify({ error: String(error) }),
2673
+ toolCallId: toolCall.id
2674
+ },
2675
+ toolName: toolCall.name
2676
+ };
2677
+ }
2678
+ }
2679
+ `.trim();
2680
+ }
2681
+ };
2682
+
2683
+ // src/cli/templates/nodes/conversation-memory.ts
2684
+ var conversationMemoryNodeTemplate = {
2685
+ id: "conversation-memory",
2686
+ name: "Conversation Memory",
2687
+ description: "Stores and retrieves conversation history",
2688
+ category: "ai",
2689
+ generate: (name) => {
2690
+ const funcName = name || "conversationMemory";
2691
+ return `
2692
+ // LLM Types
2693
+ interface LLMMessage { role: 'system' | 'user' | 'assistant' | 'tool'; content: string; toolCallId?: string; }
2694
+
2695
+ // In-memory store (replace with Redis, database, etc. for production)
2696
+ const conversations: Map<string, LLMMessage[]> = new Map();
2697
+
2698
+ /**
2699
+ * Manages conversation history for stateful chat
2700
+ *
2701
+ * @flowWeaver nodeType
2702
+ * @label ${funcName}
2703
+ * @color blue
2704
+ * @icon database
2705
+ * @input conversationId [order:1] - Unique conversation identifier
2706
+ * @input newMessage [order:2] - New message to add (optional)
2707
+ * @input maxMessages [order:3] - Max messages to retain (optional, default 50)
2708
+ * @input execute [order:0] - Execute
2709
+ * @output messages [order:2] - Full conversation history
2710
+ * @output messageCount [order:3] - Number of messages
2711
+ * @output onSuccess [order:0] - On Success
2712
+ * @output onFailure [order:1] - On Failure
2713
+ */
2714
+ function ${funcName}(
2715
+ execute: boolean,
2716
+ conversationId: string,
2717
+ newMessage?: LLMMessage,
2718
+ maxMessages?: number
2719
+ ): {
2720
+ onSuccess: boolean;
2721
+ onFailure: boolean;
2722
+ messages: LLMMessage[];
2723
+ messageCount: number;
2724
+ } {
2725
+ if (!execute) {
2726
+ return {
2727
+ onSuccess: false,
2728
+ onFailure: false,
2729
+ messages: [],
2730
+ messageCount: 0
2731
+ };
2732
+ }
2733
+
2734
+ const limit = maxMessages ?? 50;
2735
+
2736
+ // Get or create conversation
2737
+ if (!conversations.has(conversationId)) {
2738
+ conversations.set(conversationId, []);
2739
+ }
2740
+
2741
+ const history = conversations.get(conversationId)!;
2742
+
2743
+ // Add new message if provided
2744
+ if (newMessage) {
2745
+ history.push(newMessage);
2746
+
2747
+ // Trim to max length (keep system message if present)
2748
+ while (history.length > limit) {
2749
+ const firstNonSystem = history.findIndex(m => m.role !== 'system');
2750
+ if (firstNonSystem > 0) {
2751
+ history.splice(firstNonSystem, 1);
2752
+ } else {
2753
+ history.shift();
2754
+ }
2755
+ }
2756
+ }
2757
+
2758
+ return {
2759
+ onSuccess: true,
2760
+ onFailure: false,
2761
+ messages: [...history],
2762
+ messageCount: history.length
2763
+ };
2764
+ }
2765
+ `.trim();
2766
+ }
2767
+ };
2768
+
2769
+ // src/cli/templates/nodes/prompt-template.ts
2770
+ var promptTemplateNodeTemplate = {
2771
+ id: "prompt-template",
2772
+ name: "Prompt Template",
2773
+ description: "Interpolate variables into a prompt template string",
2774
+ category: "ai",
2775
+ generate: (name) => {
2776
+ const funcName = name || "promptTemplate";
2777
+ const label = toPascalCase(funcName);
2778
+ return `
2779
+ /**
2780
+ * Interpolate variables into a prompt template string.
2781
+ * Uses {{variableName}} syntax for placeholders.
2782
+ *
2783
+ * Example:
2784
+ * template: "Hello {{name}}, your order {{orderId}} is ready."
2785
+ * variables: { name: "Alice", orderId: "12345" }
2786
+ * \u2192 prompt: "Hello Alice, your order 12345 is ready."
2787
+ *
2788
+ * @flowWeaver nodeType
2789
+ * @expression
2790
+ * @label ${label}
2791
+ * @color pink
2792
+ * @icon textSnippet
2793
+ * @input template [order:0] - Template string with {{variable}} placeholders
2794
+ * @input variables [order:1] - Key-value pairs to interpolate
2795
+ * @output prompt [order:0] - Rendered prompt string
2796
+ * @output unresolvedCount [order:1] - Number of unresolved placeholders
2797
+ */
2798
+ function ${funcName}(
2799
+ template: string,
2800
+ variables: Record<string, string>
2801
+ ): {
2802
+ prompt: string;
2803
+ unresolvedCount: number;
2804
+ } {
2805
+ let unresolved = 0;
2806
+
2807
+ const prompt = template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match, key) => {
2808
+ if (key in variables) {
2809
+ return variables[key];
2810
+ }
2811
+ unresolved++;
2812
+ return match; // Leave unresolved placeholders as-is
2813
+ });
2814
+
2815
+ return { prompt, unresolvedCount: unresolved };
2816
+ }
2817
+ `.trim();
2818
+ }
2819
+ };
2820
+
2821
+ // src/cli/templates/nodes/json-extractor.ts
2822
+ var jsonExtractorNodeTemplate = {
2823
+ id: "json-extractor",
2824
+ name: "JSON Extractor",
2825
+ description: "Extract structured JSON from LLM text output",
2826
+ category: "ai",
2827
+ generate: (name) => {
2828
+ const funcName = name || "jsonExtractor";
2829
+ const label = toPascalCase(funcName);
2830
+ return `
2831
+ /**
2832
+ * Extract structured JSON from LLM text output.
2833
+ * Handles markdown code fences, leading/trailing text, and optional schema validation.
2834
+ *
2835
+ * Strips \\\`\\\`\\\`json ... \\\`\\\`\\\` fences, finds the first valid JSON object or array,
2836
+ * and optionally validates that expected field names are present.
2837
+ *
2838
+ * @flowWeaver nodeType
2839
+ * @expression
2840
+ * @label ${label}
2841
+ * @color cyan
2842
+ * @icon dataObject
2843
+ * @input text [order:0] - Raw text potentially containing JSON
2844
+ * @input schema [order:1] - Expected field names for validation (optional)
2845
+ * @output extracted [order:0] - Parsed JSON object (null if extraction failed)
2846
+ * @output valid [order:1] - Whether extraction and validation succeeded
2847
+ * @output raw [order:2] - The raw JSON string that was found
2848
+ */
2849
+ function ${funcName}(
2850
+ text: string,
2851
+ schema?: string[]
2852
+ ): {
2853
+ extracted: Record<string, unknown> | null;
2854
+ valid: boolean;
2855
+ raw: string;
2856
+ } {
2857
+ if (!text || typeof text !== 'string') {
2858
+ return { extracted: null, valid: false, raw: '' };
2859
+ }
2860
+
2861
+ // Strip markdown code fences
2862
+ let cleaned = text;
2863
+ const fenceMatch = cleaned.match(/\\\`\\\`\\\`(?:json)?\\s*([\\s\\S]*?)\\\`\\\`\\\`/);
2864
+ if (fenceMatch) {
2865
+ cleaned = fenceMatch[1].trim();
2866
+ }
2867
+
2868
+ // Find first JSON object or array via brace/bracket matching
2869
+ const startChar = cleaned.indexOf('{') !== -1 && (cleaned.indexOf('[') === -1 || cleaned.indexOf('{') < cleaned.indexOf('['))
2870
+ ? '{'
2871
+ : '[';
2872
+ const endChar = startChar === '{' ? '}' : ']';
2873
+ const startIdx = cleaned.indexOf(startChar);
2874
+
2875
+ if (startIdx === -1) {
2876
+ return { extracted: null, valid: false, raw: '' };
2877
+ }
2878
+
2879
+ // Walk forward to find the matching closing brace/bracket
2880
+ let depth = 0;
2881
+ let inString = false;
2882
+ let escape = false;
2883
+ let endIdx = -1;
2884
+
2885
+ for (let i = startIdx; i < cleaned.length; i++) {
2886
+ const ch = cleaned[i];
2887
+
2888
+ if (escape) {
2889
+ escape = false;
2890
+ continue;
2891
+ }
2892
+
2893
+ if (ch === '\\\\') {
2894
+ escape = true;
2895
+ continue;
2896
+ }
2897
+
2898
+ if (ch === '"') {
2899
+ inString = !inString;
2900
+ continue;
2901
+ }
2902
+
2903
+ if (inString) continue;
2904
+
2905
+ if (ch === startChar) depth++;
2906
+ if (ch === endChar) depth--;
2907
+
2908
+ if (depth === 0) {
2909
+ endIdx = i;
2910
+ break;
2911
+ }
2912
+ }
2913
+
2914
+ if (endIdx === -1) {
2915
+ return { extracted: null, valid: false, raw: '' };
2916
+ }
2917
+
2918
+ const raw = cleaned.slice(startIdx, endIdx + 1);
2919
+
2920
+ try {
2921
+ const parsed = JSON.parse(raw);
2922
+
2923
+ // Validate schema if provided
2924
+ if (schema && schema.length > 0 && typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
2925
+ const missingFields = schema.filter(field => !(field in parsed));
2926
+ if (missingFields.length > 0) {
2927
+ return { extracted: parsed, valid: false, raw };
2928
+ }
2929
+ }
2930
+
2931
+ return { extracted: parsed, valid: true, raw };
2932
+ } catch {
2933
+ return { extracted: null, valid: false, raw };
2934
+ }
2935
+ }
2936
+ `.trim();
2937
+ }
2938
+ };
2939
+
2940
+ // src/cli/templates/nodes/human-approval.ts
2941
+ var humanApprovalNodeTemplate = {
2942
+ id: "human-approval",
2943
+ name: "Human Approval",
2944
+ description: "Pause workflow and wait for human approval",
2945
+ category: "workflow",
2946
+ generate: (name) => {
2947
+ const funcName = name || "humanApproval";
2948
+ const label = toPascalCase(funcName);
2949
+ return `
2950
+ /**
2951
+ * Yield a durable human-approval gate.
2952
+ *
2953
+ * The generated engine never calls this body. A coordinator persists the
2954
+ * yielded continuation and gate atomically, then supplies the exact resolution
2955
+ * to a later compatible Node.js executor invocation.
2956
+ *
2957
+ * @flowWeaver nodeType
2958
+ * @durableGate approval
2959
+ * @label ${label}
2960
+ * @color orange
2961
+ * @icon verified
2962
+ * @input execute [order:0] - Execute
2963
+ * @input prompt [order:1] - Approval prompt shown to reviewer
2964
+ * @input context [order:2] - Additional context for the reviewer (optional)
2965
+ * @input timeout [order:3] - Timeout duration e.g. "7d", "1h" (optional)
2966
+ * @output onSuccess [order:0] - On Success
2967
+ * @output onFailure [order:1] - On Failure (timeout or error)
2968
+ * @output approved [order:2] - Whether the request was approved
2969
+ * @output response [order:3] - Reviewer's response text
2970
+ * @output reviewer [order:4] - Reviewer identifier
2971
+ */
2972
+ async function ${funcName}(
2973
+ execute: boolean,
2974
+ prompt: string,
2975
+ context?: Record<string, unknown>,
2976
+ timeout?: string
2977
+ ): Promise<{
2978
+ onSuccess: boolean;
2979
+ onFailure: boolean;
2980
+ approved: boolean;
2981
+ response?: string;
2982
+ reviewer?: string;
2983
+ }> {
2984
+ throw new Error(
2985
+ \`durable approval gate must not execute: \${execute}:\${prompt}:\${String(context)}:\${String(timeout)}\`,
2986
+ );
2987
+ }
2988
+ `.trim();
2989
+ }
2990
+ };
2991
+
2992
+ // src/cli/templates/nodes/agent-router.ts
2993
+ var agentRouterNodeTemplate = {
2994
+ id: "agent-router",
2995
+ name: "Agent Router",
2996
+ description: "Route to different handlers based on a classification result",
2997
+ category: "ai",
2998
+ generate: (name) => {
2999
+ const funcName = name || "agentRouter";
3000
+ const label = toPascalCase(funcName);
3001
+ return `
3002
+ // ============================================================
3003
+ // ROUTE DEFINITIONS
3004
+ // ============================================================
3005
+ //
3006
+ // Define your routes here. The router matches the 'category' input
3007
+ // (from an upstream LLM call) against route names using case-insensitive
3008
+ // comparison. The last route is used as a default/fallback.
3009
+ //
3010
+ // Example wiring in a workflow:
3011
+ // llmCall.content \u2192 agentRouter.category
3012
+ // agentRouter.selectedRoute \u2192 (use for downstream branching)
3013
+
3014
+ interface Route {
3015
+ name: string;
3016
+ description: string;
3017
+ }
3018
+
3019
+ const DEFAULT_ROUTES: Route[] = [
3020
+ { name: 'billing', description: 'Billing inquiries, invoices, payments' },
3021
+ { name: 'technical', description: 'Technical support, bugs, troubleshooting' },
3022
+ { name: 'general', description: 'General questions (default fallback)' },
3023
+ ];
3024
+
3025
+ /**
3026
+ * Route to different handlers based on a classification result.
3027
+ * Matches the category string against route names (case-insensitive).
3028
+ * Falls back to the last route if no match is found.
3029
+ *
3030
+ * @flowWeaver nodeType
3031
+ * @label ${label}
3032
+ * @color blue
3033
+ * @icon altRoute
3034
+ * @input execute [order:0] - Execute
3035
+ * @input category [order:1] - Classification result (from upstream LLM call)
3036
+ * @input routes [order:2] - Available routes with name and description (optional)
3037
+ * @output onSuccess [order:0] - On Success
3038
+ * @output onFailure [order:1] - On Failure (no routes provided)
3039
+ * @output selectedRoute [order:2] - Name of the matched route
3040
+ * @output routeDescription [order:3] - Description of the matched route
3041
+ * @output isDefault [order:4] - Whether the default/fallback route was used
3042
+ */
3043
+ function ${funcName}(
3044
+ execute: boolean,
3045
+ category: string,
3046
+ routes?: Route[]
3047
+ ): {
3048
+ onSuccess: boolean;
3049
+ onFailure: boolean;
3050
+ selectedRoute: string;
3051
+ routeDescription: string;
3052
+ isDefault: boolean;
3053
+ } {
3054
+ if (!execute) {
3055
+ return {
3056
+ onSuccess: false,
3057
+ onFailure: false,
3058
+ selectedRoute: '',
3059
+ routeDescription: '',
3060
+ isDefault: false,
3061
+ };
3062
+ }
3063
+
3064
+ const activeRoutes = routes && routes.length > 0 ? routes : DEFAULT_ROUTES;
3065
+
3066
+ if (activeRoutes.length === 0) {
3067
+ return {
3068
+ onSuccess: false,
3069
+ onFailure: true,
3070
+ selectedRoute: '',
3071
+ routeDescription: '',
3072
+ isDefault: false,
3073
+ };
3074
+ }
3075
+
3076
+ // Case-insensitive match against route names
3077
+ const normalized = (category || '').trim().toLowerCase();
3078
+ const matched = activeRoutes.find(
3079
+ (r) => r.name.toLowerCase() === normalized
3080
+ );
3081
+
3082
+ if (matched) {
3083
+ return {
3084
+ onSuccess: true,
3085
+ onFailure: false,
3086
+ selectedRoute: matched.name,
3087
+ routeDescription: matched.description,
3088
+ isDefault: false,
3089
+ };
3090
+ }
3091
+
3092
+ // Fallback to last route as default
3093
+ const fallback = activeRoutes[activeRoutes.length - 1];
3094
+ return {
3095
+ onSuccess: true,
3096
+ onFailure: false,
3097
+ selectedRoute: fallback.name,
3098
+ routeDescription: fallback.description,
3099
+ isDefault: true,
3100
+ };
3101
+ }
3102
+ `.trim();
3103
+ }
3104
+ };
3105
+
3106
+ // src/cli/templates/nodes/rag-retriever.ts
3107
+ var ragRetrieverNodeTemplate = {
3108
+ id: "rag-retriever",
3109
+ name: "RAG Retriever",
3110
+ description: "Retrieve relevant documents via vector similarity search",
3111
+ category: "ai",
3112
+ generate: (name) => {
3113
+ const funcName = name || "ragRetriever";
3114
+ const label = toPascalCase(funcName);
3115
+ return `
3116
+ // ============================================================
3117
+ // VECTOR STORE
3118
+ // ============================================================
3119
+ //
3120
+ // Replace mockRetrieve() with your vector store:
3121
+ //
3122
+ // Pinecone: const results = await index.query({ vector: embedding, topK });
3123
+ // pgvector: const results = await db.query(
3124
+ // 'SELECT text, metadata, 1 - (embedding <=> $1) AS score FROM docs ORDER BY score DESC LIMIT $2',
3125
+ // [embedding, topK]
3126
+ // );
3127
+ // Weaviate: const results = await client.graphql.get()
3128
+ // .withClassName('Document')
3129
+ // .withNearText({ concepts: [query] })
3130
+ // .withLimit(topK)
3131
+ // .do();
3132
+ // ChromaDB: const results = await collection.query({ queryTexts: [query], nResults: topK });
3133
+
3134
+ interface RetrievedDocument {
3135
+ text: string;
3136
+ score: number;
3137
+ metadata?: Record<string, unknown>;
3138
+ }
3139
+
3140
+ // Mock document store. Replace with a real vector database
3141
+ const MOCK_DOCUMENTS: Record<string, RetrievedDocument[]> = {
3142
+ default: [
3143
+ { text: 'Flow Weaver compiles workflows to standalone TypeScript functions.', score: 0.95, metadata: { source: 'docs/overview.md' } },
3144
+ { text: 'The compiler validates connections at compile time, catching errors before runtime.', score: 0.88, metadata: { source: 'docs/compiler.md' } },
3145
+ { text: 'Workflows are standard TypeScript files with JSDoc annotations.', score: 0.82, metadata: { source: 'docs/authoring.md' } },
3146
+ { text: 'Deploy compiled workflows to any supported target via installed packs.', score: 0.75, metadata: { source: 'docs/deployment.md' } },
3147
+ { text: 'The console shows each run step by step and answers paused gates from a form.', score: 0.71, metadata: { source: 'docs/console.md' } },
3148
+ ],
3149
+ };
3150
+
3151
+ async function mockRetrieve(query: string, collection: string, topK: number): Promise<RetrievedDocument[]> {
3152
+ const docs = MOCK_DOCUMENTS[collection] || MOCK_DOCUMENTS['default'] || [];
3153
+
3154
+ // Simple keyword overlap scoring (mock, since real stores use vector similarity)
3155
+ const queryWords = new Set(query.toLowerCase().split(/\\s+/));
3156
+ const scored = docs.map((doc) => {
3157
+ const docWords = doc.text.toLowerCase().split(/\\s+/);
3158
+ const overlap = docWords.filter((w) => queryWords.has(w)).length;
3159
+ const score = Math.min(0.99, overlap / Math.max(queryWords.size, 1) * 0.5 + doc.score * 0.5);
3160
+ return { ...doc, score };
3161
+ });
3162
+
3163
+ return scored
3164
+ .sort((a, b) => b.score - a.score)
3165
+ .slice(0, topK);
3166
+ }
3167
+
3168
+ /**
3169
+ * Retrieve relevant documents via vector similarity search.
3170
+ * Returns scored documents and a concatenated context string ready for LLM input.
3171
+ *
3172
+ * @flowWeaver nodeType
3173
+ * @label ${label}
3174
+ * @color green
3175
+ * @icon search
3176
+ * @input execute [order:0] - Execute
3177
+ * @input query [order:1] - Search query text
3178
+ * @input collection [order:2] - Collection/index name
3179
+ * @input topK [order:3] - Number of results (optional, default 5)
3180
+ * @output onSuccess [order:0] - On Success
3181
+ * @output onFailure [order:1] - On Failure
3182
+ * @output documents [order:2] - Retrieved documents with relevance scores
3183
+ * @output context [order:3] - Concatenated document text for LLM context
3184
+ */
3185
+ async function ${funcName}(
3186
+ execute: boolean,
3187
+ query: string,
3188
+ collection: string,
3189
+ topK?: number
3190
+ ): Promise<{
3191
+ onSuccess: boolean;
3192
+ onFailure: boolean;
3193
+ documents: RetrievedDocument[];
3194
+ context: string;
3195
+ }> {
3196
+ if (!execute) {
3197
+ return {
3198
+ onSuccess: false,
3199
+ onFailure: false,
3200
+ documents: [],
3201
+ context: '',
3202
+ };
3203
+ }
3204
+
3205
+ try {
3206
+ const limit = topK ?? 5;
3207
+ const documents = await mockRetrieve(query, collection, limit);
3208
+
3209
+ // Concatenate document texts for easy LLM context injection
3210
+ const context = documents
3211
+ .map((doc, i) => \`[Document \${i + 1} (score: \${doc.score.toFixed(2)})]
3212
+ \${doc.text}\`)
3213
+ .join('\\n\\n');
3214
+
3215
+ return {
3216
+ onSuccess: true,
3217
+ onFailure: false,
3218
+ documents,
3219
+ context,
3220
+ };
3221
+ } catch (error) {
3222
+ console.error('RAG retrieval failed:', error);
3223
+ return {
3224
+ onSuccess: false,
3225
+ onFailure: true,
3226
+ documents: [],
3227
+ context: '',
3228
+ };
3229
+ }
3230
+ }
3231
+ `.trim();
3232
+ }
3233
+ };
3234
+
3235
+ // src/cli/templates/index.ts
3236
+ var workflowTemplates = [
3237
+ sequentialTemplate,
3238
+ foreachTemplate,
3239
+ conditionalTemplate,
3240
+ approvalTemplate,
3241
+ aiAgentTemplate,
3242
+ aiReactTemplate,
3243
+ aiRagTemplate,
3244
+ aiChatTemplate,
3245
+ aggregatorTemplate,
3246
+ webhookTemplate,
3247
+ errorHandlerTemplate
3248
+ ];
3249
+ var nodeTemplates = [
3250
+ validatorNodeTemplate,
3251
+ transformerNodeTemplate,
3252
+ httpNodeTemplate,
3253
+ aggregatorNodeTemplate,
3254
+ llmCallNodeTemplate,
3255
+ toolExecutorNodeTemplate,
3256
+ conversationMemoryNodeTemplate,
3257
+ promptTemplateNodeTemplate,
3258
+ jsonExtractorNodeTemplate,
3259
+ humanApprovalNodeTemplate,
3260
+ agentRouterNodeTemplate,
3261
+ ragRetrieverNodeTemplate
3262
+ ];
3263
+ function getWorkflowTemplate(id) {
3264
+ return workflowTemplates.find((t) => t.id === id) ?? packWorkflowTemplates.find((t) => t.id === id);
3265
+ }
3266
+ function getNodeTemplate(id) {
3267
+ return nodeTemplates.find((t) => t.id === id);
3268
+ }
3269
+ var packWorkflowTemplates = [];
3270
+ function getAllWorkflowTemplates() {
3271
+ return [...workflowTemplates, ...packWorkflowTemplates];
3272
+ }
3273
+ function registerWorkflowTemplates(templates) {
3274
+ for (const tmpl of templates) {
3275
+ if (!packWorkflowTemplates.some((t) => t.id === tmpl.id)) {
3276
+ packWorkflowTemplates.push(tmpl);
3277
+ }
3278
+ }
3279
+ }
3280
+
3281
+ export {
3282
+ generateOpenAIProvider,
3283
+ generateAnthropicProvider,
3284
+ generateOllamaProvider,
3285
+ generateMockProvider,
3286
+ getProviderCode,
3287
+ LLM_CORE_TYPES,
3288
+ LLM_SIMPLE_TYPES,
3289
+ LLM_MOCK_PROVIDER,
3290
+ LLM_MOCK_PROVIDER_WITH_TOOLS,
3291
+ aiConfigSchema,
3292
+ toCamelCase,
3293
+ toPascalCase,
3294
+ workflowTemplates,
3295
+ nodeTemplates,
3296
+ getWorkflowTemplate,
3297
+ getNodeTemplate,
3298
+ getAllWorkflowTemplates,
3299
+ registerWorkflowTemplates
3300
+ };