flujo-ai 3.24.0 → 3.26.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 (363) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +233 -217
  3. package/.next/app-path-routes-manifest.json +8 -8
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/react-loadable-manifest.json +25 -20
  6. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  7. package/.next/server/app/_not-found.html +1 -1
  8. package/.next/server/app/_not-found.rsc +3 -3
  9. package/.next/server/app/api/approvals/[id]/route.js +1 -1
  10. package/.next/server/app/api/approvals/[id]/route.js.nft.json +1 -1
  11. package/.next/server/app/api/approvals/[id]/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/approvals/route.js.nft.json +1 -1
  13. package/.next/server/app/api/approvals/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/backup/route.js +1 -1
  15. package/.next/server/app/api/backup/route.js.nft.json +1 -1
  16. package/.next/server/app/api/backup/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/browse/route.js +1 -1
  18. package/.next/server/app/api/browse/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/bugs/enhance/route.js +1 -1
  20. package/.next/server/app/api/bugs/enhance/route.js.nft.json +1 -1
  21. package/.next/server/app/api/bugs/enhance/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/cwd/route.js +1 -1
  23. package/.next/server/app/api/cwd/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/encryption/secure/route.js +1 -1
  25. package/.next/server/app/api/encryption/secure/route.js.nft.json +1 -1
  26. package/.next/server/app/api/encryption/secure/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/env/route.js +1 -1
  28. package/.next/server/app/api/env/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/flow/[id]/route.js.nft.json +1 -1
  30. package/.next/server/app/api/flow/[id]/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/flow/compile/route.js.nft.json +1 -1
  32. package/.next/server/app/api/flow/compile/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/flow/generate/route.js.nft.json +1 -1
  34. package/.next/server/app/api/flow/generate/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/flow/improve/route.js.nft.json +1 -1
  36. package/.next/server/app/api/flow/improve/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/flow/prompt-renderer/route.js.nft.json +1 -1
  38. package/.next/server/app/api/flow/prompt-renderer/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/flow/quick-chat/route.js.nft.json +1 -1
  40. package/.next/server/app/api/flow/quick-chat/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/flow/repair/route.js.nft.json +1 -1
  42. package/.next/server/app/api/flow/repair/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/flow/route.js.nft.json +1 -1
  44. package/.next/server/app/api/flow/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/git/route.js +1 -1
  46. package/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/init/route.js.nft.json +1 -1
  48. package/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/local-models/capability/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/local-models/pull/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/local-models/suggest/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/mcp/cancel/route.js.nft.json +1 -1
  53. package/.next/server/app/api/mcp/cancel/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/mcp/servers/[name]/prompts/get/route.js.nft.json +1 -1
  55. package/.next/server/app/api/mcp/servers/[name]/prompts/get/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/mcp/servers/[name]/prompts/route.js.nft.json +1 -1
  57. package/.next/server/app/api/mcp/servers/[name]/prompts/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/mcp/servers/[name]/resources/read/route.js.nft.json +1 -1
  59. package/.next/server/app/api/mcp/servers/[name]/resources/read/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/mcp/servers/[name]/resources/route.js.nft.json +1 -1
  61. package/.next/server/app/api/mcp/servers/[name]/resources/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/mcp/servers/[name]/route.js +1 -1
  63. package/.next/server/app/api/mcp/servers/[name]/route.js.nft.json +1 -1
  64. package/.next/server/app/api/mcp/servers/[name]/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/mcp/servers/[name]/status/route.js.nft.json +1 -1
  66. package/.next/server/app/api/mcp/servers/[name]/status/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/mcp/servers/[name]/tools/[toolName]/route.js.nft.json +1 -1
  68. package/.next/server/app/api/mcp/servers/[name]/tools/[toolName]/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/mcp/servers/[name]/tools/route.js.nft.json +1 -1
  70. package/.next/server/app/api/mcp/servers/[name]/tools/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/mcp/servers/route.js +1 -1
  72. package/.next/server/app/api/mcp/servers/route.js.nft.json +1 -1
  73. package/.next/server/app/api/mcp/servers/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/mcp/test-connection/route.js +1 -1
  75. package/.next/server/app/api/mcp/test-connection/route.js.nft.json +1 -1
  76. package/.next/server/app/api/mcp/test-connection/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/mcp/test-connection/stream/route.js +1 -1
  78. package/.next/server/app/api/mcp/test-connection/stream/route.js.nft.json +1 -1
  79. package/.next/server/app/api/mcp/test-connection/stream/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/mcp-registry/route.js.nft.json +1 -1
  81. package/.next/server/app/api/mcp-registry/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/mcp-registry/spotlight/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/model/[id]/route.js.nft.json +1 -1
  84. package/.next/server/app/api/model/[id]/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/model/provider/route.js.nft.json +1 -1
  86. package/.next/server/app/api/model/provider/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/model/route.js.nft.json +1 -1
  88. package/.next/server/app/api/model/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/model/test/route.js.nft.json +1 -1
  90. package/.next/server/app/api/model/test/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/oauth/callback/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/oauth/initiate/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/oauth/reset/route.js.nft.json +1 -1
  94. package/.next/server/app/api/oauth/reset/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/planned-executions/[id]/route.js.nft.json +1 -1
  96. package/.next/server/app/api/planned-executions/[id]/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/planned-executions/[id]/run/route.js.nft.json +1 -1
  98. package/.next/server/app/api/planned-executions/[id]/run/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/planned-executions/[id]/runs/route.js.nft.json +1 -1
  100. package/.next/server/app/api/planned-executions/[id]/runs/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/planned-executions/preview-schedule/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/planned-executions/reconcile/route.js.nft.json +1 -1
  103. package/.next/server/app/api/planned-executions/reconcile/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/planned-executions/route.js.nft.json +1 -1
  105. package/.next/server/app/api/planned-executions/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/restore/route.js +1 -1
  107. package/.next/server/app/api/restore/route.js.nft.json +1 -1
  108. package/.next/server/app/api/restore/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/runs/active/route.js.nft.json +1 -1
  110. package/.next/server/app/api/runs/active/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/storage/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/update/route.js +1 -1
  113. package/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/waves/route.js +1 -1
  115. package/.next/server/app/api/waves/route.js.nft.json +1 -1
  116. package/.next/server/app/api/waves/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/webhooks/[id]/route.js +1 -1
  118. package/.next/server/app/api/webhooks/[id]/route.js.nft.json +1 -1
  119. package/.next/server/app/api/webhooks/[id]/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/chat/page.js +9 -9
  121. package/.next/server/app/chat/page.js.nft.json +1 -1
  122. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  123. package/.next/server/app/chat.html +1 -1
  124. package/.next/server/app/chat.rsc +4 -4
  125. package/.next/server/app/docs/page.js +11 -8
  126. package/.next/server/app/docs/page.js.nft.json +1 -1
  127. package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  128. package/.next/server/app/docs.html +1 -1
  129. package/.next/server/app/docs.rsc +4 -4
  130. package/.next/server/app/executions/page.js +3 -3
  131. package/.next/server/app/executions/page.js.nft.json +1 -1
  132. package/.next/server/app/executions/page_client-reference-manifest.js +1 -1
  133. package/.next/server/app/executions.html +1 -1
  134. package/.next/server/app/executions.rsc +4 -4
  135. package/.next/server/app/flows/page.js +3 -3
  136. package/.next/server/app/flows/page.js.nft.json +1 -1
  137. package/.next/server/app/flows/page_client-reference-manifest.js +1 -1
  138. package/.next/server/app/flows.html +1 -1
  139. package/.next/server/app/flows.rsc +4 -4
  140. package/.next/server/app/index.html +1 -1
  141. package/.next/server/app/index.rsc +4 -4
  142. package/.next/server/app/mcp/page.js +5 -5
  143. package/.next/server/app/mcp/page.js.nft.json +1 -1
  144. package/.next/server/app/mcp/page_client-reference-manifest.js +1 -1
  145. package/.next/server/app/mcp-flows/route.js +1 -1
  146. package/.next/server/app/mcp-flows/route.js.nft.json +1 -1
  147. package/.next/server/app/mcp-flows/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/mcp-proxy/[server]/route.js +1 -1
  149. package/.next/server/app/mcp-proxy/[server]/route.js.nft.json +1 -1
  150. package/.next/server/app/mcp-proxy/[server]/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/mcp.html +1 -1
  152. package/.next/server/app/mcp.rsc +4 -4
  153. package/.next/server/app/models/page.js +2 -2
  154. package/.next/server/app/models/page.js.nft.json +1 -1
  155. package/.next/server/app/models/page_client-reference-manifest.js +1 -1
  156. package/.next/server/app/page.js +2 -2
  157. package/.next/server/app/page_client-reference-manifest.js +1 -1
  158. package/.next/server/app/settings/page.js +2 -57
  159. package/.next/server/app/settings/page.js.nft.json +1 -1
  160. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  161. package/.next/server/app/settings.html +1 -1
  162. package/.next/server/app/settings.rsc +4 -4
  163. package/.next/server/app/v1/chat/completions/route.js +1 -1
  164. package/.next/server/app/v1/chat/completions/route.js.nft.json +1 -1
  165. package/.next/server/app/v1/chat/completions/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/v1/chat/conversations/[conversationId]/breakpoints/route.js +1 -1
  167. package/.next/server/app/v1/chat/conversations/[conversationId]/breakpoints/route.js.nft.json +1 -1
  168. package/.next/server/app/v1/chat/conversations/[conversationId]/breakpoints/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/v1/chat/conversations/[conversationId]/cancel/route.js +1 -1
  170. package/.next/server/app/v1/chat/conversations/[conversationId]/cancel/route.js.nft.json +1 -1
  171. package/.next/server/app/v1/chat/conversations/[conversationId]/cancel/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/continue/route.js +1 -1
  173. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/continue/route.js.nft.json +1 -1
  174. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/continue/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/step/route.js +1 -1
  176. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/step/route.js.nft.json +1 -1
  177. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/step/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/v1/chat/conversations/[conversationId]/edit-state/route.js +1 -1
  179. package/.next/server/app/v1/chat/conversations/[conversationId]/edit-state/route.js.nft.json +1 -1
  180. package/.next/server/app/v1/chat/conversations/[conversationId]/edit-state/route_client-reference-manifest.js +1 -1
  181. package/.next/server/app/v1/chat/conversations/[conversationId]/events/route.js.nft.json +1 -1
  182. package/.next/server/app/v1/chat/conversations/[conversationId]/events/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/v1/chat/conversations/[conversationId]/resources/route_client-reference-manifest.js +1 -1
  184. package/.next/server/app/v1/chat/conversations/[conversationId]/respond/route.js +1 -1
  185. package/.next/server/app/v1/chat/conversations/[conversationId]/respond/route.js.nft.json +1 -1
  186. package/.next/server/app/v1/chat/conversations/[conversationId]/respond/route_client-reference-manifest.js +1 -1
  187. package/.next/server/app/v1/chat/conversations/[conversationId]/route.js +1 -1
  188. package/.next/server/app/v1/chat/conversations/[conversationId]/route.js.nft.json +1 -1
  189. package/.next/server/app/v1/chat/conversations/[conversationId]/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/v1/chat/conversations/route.js +1 -1
  191. package/.next/server/app/v1/chat/conversations/route.js.nft.json +1 -1
  192. package/.next/server/app/v1/chat/conversations/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/v1/models/route.js.nft.json +1 -1
  194. package/.next/server/app/v1/models/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/waves/page.js +3 -3
  196. package/.next/server/app/waves/page.js.nft.json +1 -1
  197. package/.next/server/app/waves/page_client-reference-manifest.js +1 -1
  198. package/.next/server/app/waves.html +1 -1
  199. package/.next/server/app/waves.rsc +4 -4
  200. package/.next/server/app-paths-manifest.json +8 -8
  201. package/.next/server/chunks/1083.js +1 -1
  202. package/.next/server/chunks/1114.js +1 -0
  203. package/.next/server/chunks/1197.js +2 -2
  204. package/.next/server/chunks/1226.js +1 -1
  205. package/.next/server/chunks/166.js +5 -0
  206. package/.next/server/chunks/2373.js +1 -0
  207. package/.next/server/chunks/2859.js +1 -3
  208. package/.next/server/chunks/289.js +1 -1
  209. package/.next/server/chunks/3030.js +1 -1
  210. package/.next/server/chunks/3298.js +2 -0
  211. package/.next/server/chunks/3312.js +1 -0
  212. package/.next/server/chunks/3774.js +1 -1
  213. package/.next/server/chunks/3823.js +7 -7
  214. package/.next/server/chunks/3855.js +1 -0
  215. package/.next/server/chunks/3924.js +52 -0
  216. package/.next/server/chunks/4545.js +6 -2
  217. package/.next/server/chunks/4561.js +7 -7
  218. package/.next/server/chunks/4578.js +1 -0
  219. package/.next/server/chunks/4671.js +1 -1
  220. package/.next/server/chunks/4677.js +37 -0
  221. package/.next/server/chunks/4771.js +2 -2
  222. package/.next/server/chunks/4793.js +2 -0
  223. package/.next/server/chunks/4836.js +1 -0
  224. package/.next/server/chunks/5311.js +1 -1
  225. package/.next/server/chunks/5463.js +1 -0
  226. package/.next/server/chunks/5544.js +5 -0
  227. package/.next/server/chunks/5708.js +11 -8
  228. package/.next/server/chunks/584.js +1 -0
  229. package/.next/server/chunks/62.js +1 -1
  230. package/.next/server/chunks/6240.js +1 -0
  231. package/.next/server/chunks/6306.js +1 -0
  232. package/.next/server/chunks/{3928.js → 6745.js} +1 -1
  233. package/.next/server/chunks/6908.js +2 -2
  234. package/.next/server/chunks/701.js +1 -1
  235. package/.next/server/chunks/7214.js +6 -0
  236. package/.next/server/chunks/7362.js +9 -5
  237. package/.next/server/chunks/7463.js +6 -0
  238. package/.next/server/chunks/7506.js +1 -1
  239. package/.next/server/chunks/7579.js +82 -0
  240. package/.next/server/chunks/8216.js +1 -0
  241. package/.next/server/chunks/8387.js +1 -0
  242. package/.next/server/chunks/856.js +5 -0
  243. package/.next/server/chunks/8739.js +2 -2
  244. package/.next/server/chunks/9165.js +1 -0
  245. package/.next/server/chunks/94.js +1 -0
  246. package/.next/server/chunks/9427.js +1 -0
  247. package/.next/server/functions-config-manifest.json +2 -2
  248. package/.next/server/instrumentation.js.nft.json +1 -1
  249. package/.next/server/middleware-build-manifest.js +1 -1
  250. package/.next/server/middleware-manifest.json +1 -1
  251. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  252. package/.next/server/pages/404.html +1 -1
  253. package/.next/server/pages/500.html +1 -1
  254. package/.next/server/server-reference-manifest.js +1 -1
  255. package/.next/server/server-reference-manifest.json +1 -1
  256. package/.next/server/src/middleware.js +2 -2
  257. package/.next/server/src/middleware.js.map +1 -1
  258. package/.next/static/chunks/1675-773454288de4309d.js +1 -0
  259. package/.next/static/chunks/1731-6e45fb529f9044a3.js +1 -0
  260. package/.next/static/chunks/1871-14c3e63ca865d85e.js +1 -0
  261. package/.next/static/chunks/2003-7710c23acaef11c9.js +1 -0
  262. package/.next/static/chunks/2318-76fcb6c769b1a569.js +1 -0
  263. package/.next/static/chunks/2566-6e2b9d9349814789.js +1 -0
  264. package/.next/static/chunks/2734-59fbe2f62a59df86.js +1 -0
  265. package/.next/static/chunks/3089.6b4e21e1faa304e2.js +1 -0
  266. package/.next/static/chunks/3109-11bdec9bdfd996c3.js +1 -0
  267. package/.next/static/chunks/3217.f728df99ab5da33c.js +1 -0
  268. package/.next/static/chunks/333-5f3c5be57c80c48c.js +1 -0
  269. package/.next/static/chunks/3333-b7b3e5758a568013.js +1 -0
  270. package/.next/static/chunks/3556-3b6f7c99b015b752.js +1 -0
  271. package/.next/static/chunks/{6257-ee5d8d88050d7705.js → 4003-3b3768446ae333df.js} +1 -1
  272. package/.next/static/chunks/4523-a540747aa2ed34e8.js +1 -0
  273. package/.next/static/chunks/4635-0fe310d3be64e71e.js +1 -0
  274. package/.next/static/chunks/4690-ec7d397cfacedac3.js +1 -0
  275. package/.next/static/chunks/4775-cb9c0be621363a08.js +8 -0
  276. package/.next/static/chunks/5336-81da1080de29ebfc.js +1 -0
  277. package/.next/static/chunks/5512.d01d565f73109a1a.js +1 -0
  278. package/.next/static/chunks/6691-117567b2b40cd9f4.js +1 -0
  279. package/.next/static/chunks/7274-1184563607f2b5f5.js +1 -0
  280. package/.next/static/chunks/8166-e75acdc559b34fcd.js +1 -0
  281. package/.next/static/chunks/8345.fbc0af16acce7256.js +1 -0
  282. package/.next/static/chunks/8405.e728bc83a7c9fed6.js +1 -0
  283. package/.next/static/chunks/8470-72cf748472d4d501.js +1 -0
  284. package/.next/static/chunks/8607-5787e42775fc3acb.js +1 -0
  285. package/.next/static/chunks/8610-660d5088bc1dd7a7.js +1 -0
  286. package/.next/static/chunks/8834-faf121e257b517d5.js +1 -0
  287. package/.next/static/chunks/8989-401559d9f3bc80a0.js +1 -0
  288. package/.next/static/chunks/{9164-d9f1abba780231e0.js → 9164-829ab5b085ec06d6.js} +1 -1
  289. package/.next/static/chunks/9240-d0a51f4d504f34b1.js +1 -0
  290. package/.next/static/chunks/9562-b7922ceb400ec536.js +1 -0
  291. package/.next/static/chunks/9704-6b7415964d7c042a.js +1 -0
  292. package/.next/static/chunks/app/chat/page-04ad1fad78048afb.js +1 -0
  293. package/.next/static/chunks/app/docs/page-5475c616764dbb18.js +1 -0
  294. package/.next/static/chunks/app/executions/page-c18708ed96d228ec.js +1 -0
  295. package/.next/static/chunks/app/flows/page-f7e44aa545bcc56e.js +1 -0
  296. package/.next/static/chunks/app/layout-e6fbae80e0f456a6.js +1 -0
  297. package/.next/static/chunks/app/mcp/page-3638fbee04a3a6ea.js +1 -0
  298. package/.next/static/chunks/app/models/error-5732fbb053e182c5.js +1 -0
  299. package/.next/static/chunks/app/models/page-e690a986047b1e62.js +1 -0
  300. package/.next/static/chunks/app/{page-a859e4dbd180df98.js → page-0a95c40a65dbd2eb.js} +1 -1
  301. package/.next/static/chunks/app/settings/page-3ef9b95187e18a5a.js +1 -0
  302. package/.next/static/chunks/app/waves/page-c9a307e2236423a4.js +1 -0
  303. package/.next/static/chunks/webpack-a6844e1074885c2f.js +1 -0
  304. package/.next/static/css/40f9bef305b11bf5.css +1 -0
  305. package/.next/trace +10 -8
  306. package/README.md +31 -1
  307. package/package.json +1 -1
  308. package/.next/server/chunks/1119.js +0 -1
  309. package/.next/server/chunks/1439.js +0 -1
  310. package/.next/server/chunks/1910.js +0 -37
  311. package/.next/server/chunks/1999.js +0 -1
  312. package/.next/server/chunks/2246.js +0 -1
  313. package/.next/server/chunks/2823.js +0 -6
  314. package/.next/server/chunks/2998.js +0 -52
  315. package/.next/server/chunks/3286.js +0 -6
  316. package/.next/server/chunks/3291.js +0 -1
  317. package/.next/server/chunks/4637.js +0 -81
  318. package/.next/server/chunks/6644.js +0 -1
  319. package/.next/server/chunks/7427.js +0 -1
  320. package/.next/server/chunks/7723.js +0 -1
  321. package/.next/server/chunks/7769.js +0 -6
  322. package/.next/server/chunks/8518.js +0 -2
  323. package/.next/static/chunks/1620-0d8ecd877f123f7b.js +0 -1
  324. package/.next/static/chunks/1871-dd8c10ed9d37100b.js +0 -1
  325. package/.next/static/chunks/1983-242862b3dc022a26.js +0 -1
  326. package/.next/static/chunks/2003-460f30484998c05d.js +0 -1
  327. package/.next/static/chunks/2619-04bc32f026a0d946.js +0 -1
  328. package/.next/static/chunks/3217.058098140ec3f563.js +0 -1
  329. package/.next/static/chunks/3454-a8db9caba457e5fa.js +0 -1
  330. package/.next/static/chunks/3730-149f2f058529f75f.js +0 -1
  331. package/.next/static/chunks/3736-5e2b3f6cda1bb923.js +0 -1
  332. package/.next/static/chunks/4207-41abb9622eb4b4f8.js +0 -1
  333. package/.next/static/chunks/4749-f8796d16ff604d54.js +0 -1
  334. package/.next/static/chunks/4812-4a9aceb49632a973.js +0 -1
  335. package/.next/static/chunks/5501-f5b093c8dfd74196.js +0 -1
  336. package/.next/static/chunks/6016.8201fa15ab6aa90e.js +0 -1
  337. package/.next/static/chunks/6288-a285bbbd701e0dbf.js +0 -1
  338. package/.next/static/chunks/6731-c230e88cf0032609.js +0 -1
  339. package/.next/static/chunks/7430-6e78aaeac66988a9.js +0 -1
  340. package/.next/static/chunks/7583.7af90b94e3c263f2.js +0 -1
  341. package/.next/static/chunks/7687-7edf1a6e1f063b08.js +0 -1
  342. package/.next/static/chunks/8083.16fda2c7f6d10d0c.js +0 -1
  343. package/.next/static/chunks/8480-229fd353b68b570f.js +0 -1
  344. package/.next/static/chunks/8548-8e4a95334064e8b2.js +0 -1
  345. package/.next/static/chunks/8611-f6d51119761d52ff.js +0 -8
  346. package/.next/static/chunks/8834-bda798efab40c60a.js +0 -1
  347. package/.next/static/chunks/9356-99ba407b60b9dfe9.js +0 -1
  348. package/.next/static/chunks/9451-680fa09f81f18806.js +0 -1
  349. package/.next/static/chunks/9659-a279e3aaba407251.js +0 -1
  350. package/.next/static/chunks/app/chat/page-6a5b5f9ea2542fb3.js +0 -1
  351. package/.next/static/chunks/app/docs/page-935b0386917b91bb.js +0 -1
  352. package/.next/static/chunks/app/executions/page-d72027b0179e8fa2.js +0 -1
  353. package/.next/static/chunks/app/flows/page-fbce5abe34500f28.js +0 -1
  354. package/.next/static/chunks/app/layout-2ebf01d97702a18a.js +0 -1
  355. package/.next/static/chunks/app/mcp/page-8666173926cabf31.js +0 -1
  356. package/.next/static/chunks/app/models/error-a3183f168e8a9b04.js +0 -1
  357. package/.next/static/chunks/app/models/page-18dbd8e01cf87e98.js +0 -1
  358. package/.next/static/chunks/app/settings/page-7a68583660508ffd.js +0 -1
  359. package/.next/static/chunks/app/waves/page-ec33cf79f6103a9e.js +0 -1
  360. package/.next/static/chunks/webpack-f4a471ab560eb19e.js +0 -1
  361. package/.next/static/css/39393a79f7cb0dee.css +0 -1
  362. /package/.next/static/{eUM7C1boixGI469h5wtIk → Il6IDWxf3CN0dv-P6QQrp}/_buildManifest.js +0 -0
  363. /package/.next/static/{eUM7C1boixGI469h5wtIk → Il6IDWxf3CN0dv-P6QQrp}/_ssgManifest.js +0 -0
@@ -1,6 +0,0 @@
1
- "use strict";exports.id=3286,exports.ids=[3286],exports.modules={13516:(a,b,c)=>{c.d(b,{G:()=>d});let d={LOG_LEVEL:3,INCLUDE_TOOL_CALLS_IN_RESPONSE:!0,ENABLE_EXECUTION_TRACKER:!1}},32631:(a,b,c)=>{c.d(b,{D:()=>h}),c(21124);var d=c(38301),e=c(19815);c(84040),c(9718);let f=(0,e.h)("frontend/contexts/ThemeContext"),g=(0,d.createContext)(void 0),h=()=>{let a=(0,d.useContext)(g);if(!a)throw f.error("useTheme hook used outside of ThemeProvider"),Error("useTheme must be used within a ThemeProvider");return f.debug("useTheme hook accessed"),a}},32720:(a,b,c)=>{c.d(b,{A:()=>B});var d=c(21124),e=c(38301),f=c(40512),g=c(83899),h=c(52327),i=c(81637),j=c(43312),k=c(44079),l=c(37674),m=c(41893),n=c(88745),o=c(8521),p=c(79515),q=c(89490),r=c(75983),s=c(50553),t=c(84233),u=c(19925),v=c(68730),w=c(30717),x=c(98810),y=c(52399),z=c(91314);let A=(0,c(19815).h)("frontend/components/shared/FolderPickerDialog"),B=({open:a,title:b="Choose a folder",selectFiles:c=!1,initialPath:B,onClose:C,onSelect:D})=>{let[E,F]=(0,e.useState)(null),[G,H]=(0,e.useState)(""),[I,J]=(0,e.useState)(!1),[K,L]=(0,e.useState)(null),M=(0,e.useCallback)(async a=>{J(!0),L(null);try{let b=a?`?path=${encodeURIComponent(a)}`:"",c=await fetch(`/api/browse${b}`),d=await c.json();if(!c.ok||d.error)return void L(d.error||`HTTP ${c.status}`);F(d),H(d.path)}catch(a){A.warn("Browse failed",a),L("Could not reach the backend to browse folders.")}finally{J(!1)}},[]);(0,e.useEffect)(()=>{a?M(B||void 0):(F(null),L(null))},[a,B,M]);let N=a=>{D(a),C()};return(0,d.jsxs)(f.A,{open:a,onClose:C,maxWidth:"sm",fullWidth:!0,children:[(0,d.jsx)(g.A,{children:b}),(0,d.jsxs)(h.A,{dividers:!0,sx:{display:"flex",flexDirection:"column",gap:1.5},children:[(0,d.jsxs)(i.default,{sx:{display:"flex",alignItems:"center",gap:1},children:[(0,d.jsx)(j.A,{title:"Up one folder",children:(0,d.jsx)("span",{children:(0,d.jsx)(k.A,{size:"small",disabled:!E?.parent||I,onClick:()=>E?.parent&&void M(E.parent),children:(0,d.jsx)(y.A,{fontSize:"small"})})})}),(0,d.jsx)(j.A,{title:"Home folder",children:(0,d.jsx)("span",{children:(0,d.jsx)(k.A,{size:"small",disabled:I,onClick:()=>void M(),children:(0,d.jsx)(z.A,{fontSize:"small"})})})}),(0,d.jsx)(l.A,{fullWidth:!0,size:"small",value:G,onChange:a=>H(a.target.value),onKeyDown:a=>{"Enter"===a.key&&(a.preventDefault(),M(G))},placeholder:"Type a path and press Enter"})]}),E&&E.drives.length>0&&(0,d.jsx)(i.default,{sx:{display:"flex",gap:.75,flexWrap:"wrap"},children:E.drives.map(a=>(0,d.jsx)(m.A,{label:a,size:"small",variant:E.path.toLowerCase().startsWith(a.toLowerCase())?"filled":"outlined",onClick:()=>void M(a)},a))}),K&&(0,d.jsx)(n.A,{severity:"error",children:K}),(0,d.jsxs)(i.default,{sx:{minHeight:240,maxHeight:"45vh",overflow:"auto",border:1,borderColor:"divider",borderRadius:1},children:[I&&(0,d.jsx)(i.default,{sx:{display:"flex",justifyContent:"center",py:4},children:(0,d.jsx)(o.default,{size:24})}),!I&&E&&0===E.entries.length&&(0,d.jsx)(p.default,{variant:"body2",color:"text.secondary",sx:{p:2},children:"This folder is empty."}),!I&&(0,d.jsx)(q.A,{dense:!0,disablePadding:!0,children:E?.entries.map(a=>(0,d.jsxs)(r.A,{disabled:!a.isDirectory&&!c,onClick:()=>a.isDirectory?void M(a.path):N(a.path),children:[(0,d.jsx)(s.A,{sx:{minWidth:34},children:a.isDirectory?(0,d.jsx)(w.A,{fontSize:"small",color:"primary"}):(0,d.jsx)(x.A,{fontSize:"small"})}),(0,d.jsx)(t.A,{primary:a.name,primaryTypographyProps:{noWrap:!0}})]},a.path))})]})]}),(0,d.jsxs)(u.A,{children:[(0,d.jsx)(v.A,{onClick:C,children:"Cancel"}),(0,d.jsx)(v.A,{variant:"contained",disabled:!E||I,onClick:()=>E&&N(E.path),children:"Select this folder"})]})]})}},33799:(a,b,c)=>{c.d(b,{b:()=>f,c:()=>g});var d=c(50648);async function e(a,b){try{let c=await fetch("/api/git",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!c.ok||!c.body)return null;let e=null;return await (0,d.z)(c,a=>{"stdout"===a.type||"stderr"===a.type?b(a.data):"result"===a.type&&(e={success:a.success,output:a.commandOutput??""})}),e}catch(a){return console.error("Error streaming git command:",a),null}}let f=async(a,b,c)=>{if(c){let d=await e({action:"installStream",savePath:a,installCommand:b},c);if(d)return{success:d.success,message:d.success?{type:"success",text:"Dependencies installed successfully. You can now build the server."}:{type:"error",text:"Error installing dependencies. You can still try to build the server."},output:d.output||"No output was returned from the installation process."}}try{let c=await fetch("/api/git",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"install",savePath:a,installCommand:b})}),d=await c.json();if(!c.ok)throw Error(d.error||"Failed to install dependencies");return{success:!0,message:{type:"success",text:"Dependencies installed successfully. You can now build the server."},output:d.commandOutput||"No output was returned from the installation process."}}catch(a){return console.error("Error installing dependencies:",a),{success:!1,message:{type:"error",text:`Error installing dependencies: ${a.message||"Unknown error"}. You can still try to build the server.`},output:a instanceof Response?await a.text():a?.message||"Unknown error"}}},g=async(a,b,c)=>{if(c){let d=await e({action:"buildStream",savePath:a,buildCommand:b},c);if(d)return{success:d.success,message:d.success?{type:"success",text:"Server built successfully."}:{type:"error",text:"Error building server."},output:d.output||"No output was returned from the build process."}}try{let c=await fetch("/api/git",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"build",savePath:a,buildCommand:b})}),d=await c.json();if(!c.ok)throw Error(d.error||"Failed to build repository");return{success:!0,message:{type:"success",text:"Server built successfully."},output:d.commandOutput||"No output was returned from the build process."}}catch(a){return console.error("Error building server:",a),{success:!1,message:{type:"error",text:`Error building server: ${a.message||"Unknown error"}.`},output:a instanceof Response?await a.text():a?.message||"Unknown error"}}}},44920:(a,b,c)=>{function d(a){let b={};if(!a)return b;for(let[c,d]of Object.entries(a))b[c]=d&&"object"==typeof d&&"value"in d?d.value:"string"==typeof d?d:"";return b}function e(a){let b,c=[],d=[];if("string"==typeof a)try{b=JSON.parse(a)}catch(a){return{servers:d,errors:[`Invalid JSON: ${a.message}`]}}else b=a;if(!b||"object"!=typeof b)return{servers:d,errors:["Expected a JSON object."]};let e=b,f=e.mcpServers&&"object"==typeof e.mcpServers?e.mcpServers:e;if(0===Object.keys(f).length)return{servers:d,errors:['No servers found. Expected an "mcpServers" object.']};for(let[a,b]of Object.entries(f)){if(!b||"object"!=typeof b){c.push(`"${a}": entry is not an object.`);continue}let e=function(a){let b=(a.transport||a.type||"").toString().toLowerCase().trim();if(!b)return"stdio";switch(b){case"stdio":return"stdio";case"http":case"streamable-http":case"streamable":case"streamablehttp":return"streamable";case"sse":return"sse";case"ws":case"websocket":return"websocket";default:return null}}(b);if(!e){c.push(`"${a}": unknown transport type "${b.type||b.transport}".`);continue}let f={};if(b.env&&"object"==typeof b.env)for(let[a,c]of Object.entries(b.env))f[a]="string"==typeof c?c:String(c??"");let g={name:a,env:f,disabled:b.disabled??!1,autoApprove:Array.isArray(b.autoApprove)?b.autoApprove:[],rootPath:"",_buildCommand:"",_installCommand:""};if("stdio"===e){if(!b.command||"string"!=typeof b.command){c.push(`"${a}": stdio server is missing a "command".`);continue}d.push({...g,transport:"stdio",command:b.command,args:Array.isArray(b.args)?b.args:[]})}else if("websocket"===e){let e=b.url||b.websocketUrl;if(!e){c.push(`"${a}": websocket server is missing a "url".`);continue}d.push({...g,transport:"websocket",websocketUrl:e})}else{let f=b.url||b.serverUrl;if(!f){c.push(`"${a}": ${e} server is missing a "url".`);continue}let h=b.headers&&"object"==typeof b.headers?b.headers:void 0;d.push({...g,transport:e,serverUrl:f,...h?{headers:h}:{}})}}return{servers:d,errors:c}}c.d(b,{_i:()=>f,CZ:()=>h,Kt:()=>g});let f=[{id:"claude",label:"Claude",fileName:"mcp_config.json",export:function(a,b={}){let c=(b.proxyBaseUrl||"").replace(/\/$/,""),e={};for(let b of a){if(b.exposeAsMcpServer){e[b.name]={type:"http",url:`${c}/mcp-proxy/${b.name}`};continue}let a={},f=d(b.env);switch(b.transport){case"stdio":a.command=b.command,a.args=b.args||[],Object.keys(f).length>0&&(a.env=f);break;case"streamable":a.type="http",a.url=b.serverUrl,b.headers&&Object.keys(b.headers).length>0&&(a.headers=d(b.headers)),Object.keys(f).length>0&&(a.env=f);break;case"sse":a.type="sse",a.url=b.serverUrl,b.headers&&Object.keys(b.headers).length>0&&(a.headers=d(b.headers)),Object.keys(f).length>0&&(a.env=f);break;case"websocket":a.type="ws",a.url=b.websocketUrl,Object.keys(f).length>0&&(a.env=f);break;default:Object.keys(f).length>0&&(a.env=f)}e[b.name]=a}return{mcpServers:e}},import:e},{id:"cline",label:"Cline",fileName:"cline_mcp_settings.json",export:function(a,b={}){let c=(b.proxyBaseUrl||"").replace(/\/$/,""),e={};for(let b of a){let a={disabled:b.disabled??!1,autoApprove:b.autoApprove??[],timeout:60};if(b.exposeAsMcpServer){e[b.name]={...a,type:"streamableHttp",url:`${c}/mcp-proxy/${b.name}`};continue}let f=d(b.env),g={...a};switch(b.transport){case"stdio":g.command=b.command,g.args=b.args||[],Object.keys(f).length>0&&(g.env=f);break;case"streamable":g.type="streamableHttp",g.url=b.serverUrl,b.headers&&Object.keys(b.headers).length>0&&(g.headers=d(b.headers));break;case"sse":g.type="sse",g.url=b.serverUrl,b.headers&&Object.keys(b.headers).length>0&&(g.headers=d(b.headers));break;case"websocket":g.type="ws",g.url=b.websocketUrl;break;default:Object.keys(f).length>0&&(g.env=f)}e[b.name]=g}return{mcpServers:e}},import:function(a){return e(a)}}];function g(a){return f.find(b=>b.id===a)??f[0]}function h(a,b,c,d="claude"){let e=(c||"").replace(/\/$/,"");return JSON.stringify(b?g(d).export([b],{proxyBaseUrl:e}):{mcpServers:{[a]:{type:"http",url:`${e}/mcp-proxy/${a}`}}},null,2)}},46393:(a,b,c)=>{c.d(b,{A:()=>ag});var d=c(21124),e=c(38301),f=c(19815),g=c(84040),h=c(8165),i=c(93083),j=c(65343),k=c(53222),l=c(12033),m=c(91034),n=c(95786),o=c(64956),p=c(55641),q=c(29320),r=c(5748),s=c(38941),t=c(51694),u=c(1312),v=c(25750),w=c(61615),x=c(78352),y=c(28055),z=c(44920),A=c(41893),B=c(56685),C=c(71756),D=c(91901),E=c(83013);let F=({transport:a,size:b="small"})=>{let c=(()=>{switch(a){case"stdio":return{label:"STDIO",icon:(0,d.jsx)(B.A,{fontSize:"small"}),color:"#1976d2",bgColor:"#e3f2fd"};case"websocket":return{label:"WebSocket",icon:(0,d.jsx)(C.A,{fontSize:"small"}),color:"#2e7d32",bgColor:"#e8f5e8"};case"sse":return{label:"SSE",icon:(0,d.jsx)(D.A,{fontSize:"small"}),color:"#f57c00",bgColor:"#fff3e0"};case"streamable":return{label:"HTTP Stream",icon:(0,d.jsx)(E.A,{fontSize:"small"}),color:"#00796b",bgColor:"#e0f2f1"};default:return{label:"UNKNOWN",icon:(0,d.jsx)(B.A,{fontSize:"small"}),color:"#757575",bgColor:"#f5f5f5"}}})();return(0,d.jsx)(A.A,{icon:c.icon,label:c.label,size:b,sx:{backgroundColor:c.bgColor,color:c.color,fontWeight:500,fontSize:"small"===b?"0.75rem":"0.875rem",height:"small"===b?24:32,"& .MuiChip-icon":{color:c.color}}})};var G=c(40512),H=c(83899),I=c(52327),J=c(19925),K=c(68730),L=c(81637),M=c(79515),N=c(88745),O=c(95587),P=c(77028),Q=c(89490),R=c(71439),S=c(50553),T=c(84233),U=c(72264),V=c(53455),W=c(33799);let X=(0,f.h)("frontend/components/mcp/MCPServerManager/ServerUpdateDialog"),Y=({open:a,onClose:b,serverName:c,rootPath:f,installCommand:g,buildCommand:i,enabled:k,updateInfo:l,onToggle:m,onUpdated:n})=>{let[o,p]=(0,e.useState)(null),[q,r]=(0,e.useState)(!1),[s,t]=(0,e.useState)(!1),[u,x]=(0,e.useState)(!1),[y,z]=(0,e.useState)(null),[B,C]=(0,e.useState)({}),[D,E]=(0,e.useState)(""),F=!!(g&&g.trim()),Y=!!(i&&i.trim()),Z=[{key:"stop",label:"Stop server",active:k},{key:"pull",label:"Pull latest changes",active:!0},{key:"install",label:`Install dependencies (${g})`,active:F},{key:"build",label:`Build (${i})`,active:Y},{key:"restart",label:"Restart server",active:k}];(0,e.useEffect)(()=>{a&&(r(!1),t(!1),x(!1),z(null),C({}),E(""))},[a,c]),(0,e.useEffect)(()=>{if(a&&l.remoteUrl&&l.localSha&&l.remoteSha){let a=!1;return(0,V.Qz)(l.remoteUrl,l.localSha,l.remoteSha).then(b=>{a||p(b)}),()=>{a=!0}}p(null)},[a,l.remoteUrl,l.localSha,l.remoteSha]);let $=(0,e.useCallback)((a,b)=>{C(c=>({...c,[a]:b}))},[]),_=(0,e.useCallback)((a,b)=>{E(c=>c+(c?"\n":"")+`--- ${a} ---
2
- `+(b||"").trim()+"\n")},[]),aa=async()=>{t(!0),z(null),X.info(`Starting update for server ${c}`);let a=(a,b)=>{$(a,"error"),z(b),t(!1)};try{k&&($("stop","running"),await Promise.resolve(m(!1)),$("stop","done")),$("pull","running");let b=await (0,V.Qv)(f);if(!b.success)return void a("pull",b.error||"Failed to pull updates");if(_("Pull",`Updated ${(0,V.Fu)(b.oldSha)} -> ${(0,V.Fu)(b.newSha)}`),$("pull","done"),F){$("install","running");let b=await (0,W.b)(f,g.trim());if(_("Install",b.output),!b.success)return void a("install",b.message.text);$("install","done")}if(Y){$("build","running");let b=await (0,W.c)(f,i.trim());if(_("Build",b.output),!b.success)return void a("build",b.message.text);$("build","done")}k&&($("restart","running"),await Promise.resolve(m(!0)),$("restart","done")),X.info(`Update completed for server ${c}`),x(!0),t(!1),n?.()}catch(a){X.error(`Update failed for server ${c}`,a),z(a.message||"Update failed"),t(!1)}},ab=s||u||Object.keys(B).length>0,ac=l.hasLocalChanges&&!q;return(0,d.jsxs)(G.A,{open:a,onClose:s?void 0:b,maxWidth:"sm",fullWidth:!0,onClick:a=>a.stopPropagation(),children:[(0,d.jsxs)(H.A,{component:"div",sx:{display:"flex",alignItems:"center",gap:1},children:[(0,d.jsx)(v.A,{color:"primary"}),"Update ",c]}),(0,d.jsxs)(I.A,{children:[(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center",gap:1,mb:1,flexWrap:"wrap"},children:[(0,d.jsx)(A.A,{size:"small",label:(0,V.Fu)(l.localSha),sx:{fontFamily:"monospace"}}),(0,d.jsx)(M.default,{variant:"body2",color:"text.secondary",children:"→"}),(0,d.jsx)(A.A,{size:"small",color:"primary",label:(0,V.Fu)(l.remoteSha),sx:{fontFamily:"monospace"}}),l.branch&&"HEAD"!==l.branch&&(0,d.jsxs)(M.default,{variant:"body2",color:"text.secondary",children:["on ",(0,d.jsx)("code",{children:l.branch})]}),o?.behindBy!=null&&(0,d.jsxs)(M.default,{variant:"body2",color:"text.secondary",children:["(",o.behindBy," commit",1===o.behindBy?"":"s"," behind)"]})]}),l.repoRoot&&l.repoRoot.replace(/\\/g,"/").replace(/\/+$/,"").toLowerCase()!==f.replace(/\\/g,"/").replace(/\/+$/,"").toLowerCase()&&(0,d.jsxs)(M.default,{variant:"body2",color:"text.secondary",sx:{mb:1},children:["This server lives inside a larger repository — the update pulls"," ",(0,d.jsx)("code",{children:l.repoRoot})," as a whole (other servers from the same repository are updated along with it)."]}),o&&o.commits.length>0&&!ab&&(0,d.jsx)(L.default,{sx:{mb:2,p:1,borderRadius:1,border:"1px solid",borderColor:"divider",maxHeight:160,overflow:"auto"},children:o.commits.map(a=>(0,d.jsxs)(M.default,{variant:"body2",sx:{fontSize:"0.8rem"},noWrap:!0,title:a.message,children:[(0,d.jsx)("code",{children:a.sha})," ",a.message]},a.sha))}),l.hasLocalChanges&&!ab&&(0,d.jsxs)(N.A,{severity:"warning",sx:{mb:2},children:[(0,d.jsxs)(M.default,{variant:"body2",sx:{mb:1},children:["This repository has local changes to tracked files. Updating will ",(0,d.jsx)("strong",{children:"discard"})," them. Untracked files (e.g. a ",(0,d.jsx)("code",{children:".env"})," you created) and all FLUJO settings for this server are kept."]}),(0,d.jsx)(L.default,{component:"ul",sx:{m:0,pl:3,maxHeight:100,overflow:"auto"},children:l.dirtyFiles.map(a=>(0,d.jsx)("li",{children:(0,d.jsx)(M.default,{variant:"body2",component:"span",sx:{fontFamily:"monospace",fontSize:"0.8rem"},children:a})},a))}),(0,d.jsx)(O.A,{sx:{mt:1},control:(0,d.jsx)(P.A,{size:"small",checked:q,onChange:a=>r(a.target.checked)}),label:(0,d.jsx)(M.default,{variant:"body2",children:"Discard my local changes and update"})})]}),(0,d.jsx)(Q.A,{dense:!0,disablePadding:!0,children:Z.filter(a=>a.active).map(a=>(0,d.jsxs)(R.Ay,{disableGutters:!0,sx:{py:.25},children:[(0,d.jsx)(S.A,{sx:{minWidth:32},children:(a=>{switch(a){case"running":return(0,d.jsx)(w.default,{size:"small",color:"primary"});case"done":return(0,d.jsx)(h.A,{color:"success",fontSize:"small"});case"error":return(0,d.jsx)(j.A,{color:"error",fontSize:"small"});default:return(0,d.jsx)(U.A,{color:"disabled",fontSize:"small"})}})(B[a.key])}),(0,d.jsx)(T.A,{primary:a.label,primaryTypographyProps:{variant:"body2",noWrap:!0,title:a.label}})]},a.key))}),y&&(0,d.jsxs)(N.A,{severity:"error",sx:{mt:2,whiteSpace:"pre-wrap"},children:[y,k&&(0,d.jsx)(M.default,{variant:"body2",sx:{mt:1},children:"The server was left stopped. Adjust the install/build commands via Edit, then re-enable it."})]}),u&&(0,d.jsxs)(N.A,{severity:"success",sx:{mt:2},children:["Server updated successfully",k?" and restarted":"","."]}),D&&(0,d.jsx)(L.default,{sx:{mt:2,p:1,borderRadius:1,bgcolor:"background.paper",border:"1px solid",borderColor:"divider",fontFamily:"monospace",fontSize:"0.75rem",whiteSpace:"pre-wrap",overflow:"auto",maxHeight:200},children:D})]}),(0,d.jsxs)(J.A,{children:[(0,d.jsx)(K.A,{onClick:b,disabled:s,children:u?"Close":"Cancel"}),!u&&(0,d.jsx)(K.A,{variant:"contained",color:"primary",startIcon:(0,d.jsx)(v.A,{}),onClick:aa,disabled:s||ac,children:s?"Updating…":y?"Retry Update":"Update"})]})]})};var Z=c(30873),$=c(60839),_=c(30818),aa=c(27114),ab=c(43312),ac=c(44079),ad=c(67191),ae=c(98463);let af=(0,f.h)("frontend/components/mcp/MCPServerManager/ServerCard"),ag=({name:a,status:b,path:f,enabled:B,transport:C,onToggle:D=()=>{},onRetry:E=()=>{},onDelete:O=()=>{},onClick:Q,onEdit:R=()=>{},onAuthenticate:S,pickerMode:T=!1,error:U,stderrOutput:W,authorizationUrl:X,selected:ag=!1,onSelect:ah,selectionMode:ai=!1,hasOAuthTokens:aj=!1,exposeAsMcpServer:ak=!1,enableMcpApps:al=!1,updateInfo:am,installCommand:an,buildCommand:ao,onUpdated:ap,folder:aq,folders:ar=[],onSetFolder:as,builtIn:at=!1,serverConfig:au})=>{let[av,aw]=(0,e.useState)(!1),[ax,ay]=(0,e.useState)(null),[az,aA]=(0,e.useState)(!1),[aB,aC]=(0,e.useState)(!1),[aD,aE]=(0,e.useState)(""),[aF,aG]=(0,e.useState)("success"),[aH,aI]=(0,e.useState)(!1),[aJ,aK]=(0,e.useState)(!1),[aL,aM]=(0,e.useState)(ak),[aN,aO]=(0,e.useState)(al);(0,$.A)(),(0,e.useEffect)(()=>{aM(ak)},[ak]),(0,e.useEffect)(()=>{aO(al)},[al]);let aP=async b=>{aM(b);let c=await y.S.updateServerConfig(a,{exposeAsMcpServer:b});"success"in c&&c.success?(aE(b?"Server is now exposed to external apps.":"Server is no longer exposed."),aG("success")):(aM(!b),aE("Failed to update exposure setting."),aG("error")),aC(!0)},aQ=async b=>{aO(b);let c=await y.S.updateServerConfig(a,{enableMcpApps:b});"success"in c&&c.success?(aE(b?"This server may now render interactive apps in chat (sandboxed).":"Interactive apps disabled for this server."),aG("success")):(aO(!b),aE("Failed to update the MCP Apps setting."),aG("error")),aC(!0)},aR=()=>{navigator.clipboard.writeText(""),aE("Endpoint URL copied to clipboard."),aG("success"),aC(!0)},aS=()=>{navigator.clipboard.writeText((0,z.CZ)(a,au,"")),aE("Server JSON copied to clipboard."),aG("success"),aC(!0)},aT={connected:"success.main",disconnected:"text.secondary",error:"error.main",connecting:"info.main",initialization:"info.main",requires_authentication:"warning.main"}[b];(0,e.useEffect)(()=>{if(("connecting"===b||"initialization"===b)&&B&&!T){aI(!0);let b=setTimeout(()=>{af.debug(`Polling status for server: ${a}`),E()},2e3);return()=>{clearTimeout(b),aI(!1)}}"connecting"!==b&&"initialization"!==b&&aI(!1)},[b,B,a,E]);let[aU,aV]=(0,e.useState)(null);(0,e.useEffect)(()=>()=>{aU&&clearTimeout(aU)},[aU]);let aW=async b=>{b.stopPropagation(),af.debug(`Reset OAuth tokens button clicked for server: ${a}`),aK(!0);try{let b=await fetch("/api/oauth/reset",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({serverName:a})});if(!b.ok){let a=await b.json();throw Error(a.error||"Failed to reset OAuth tokens")}let c=await b.json();af.info(`OAuth tokens reset successfully for ${a}`,c),aE("OAuth tokens reset successfully. Server will require re-authentication."),aG("success"),aC(!0),setTimeout(()=>{E()},500)}catch(b){af.error(`Failed to reset OAuth tokens for ${a}`,b),aE(`Failed to reset OAuth tokens: ${b instanceof Error?b.message:"Unknown error"}`),aG("error"),aC(!0)}finally{aK(!1)}},{getThemeValue:aX,getThemeColor:aY,colors:aZ}=(0,g.Ic)(),a$=()=>{af.debug(`Server restart initiated for: ${a}`),D(!1),setTimeout(()=>{D(!0),af.info(`Server ${a} restarted`)},1e3)};return(0,d.jsxs)(_.A,{role:T?"button":void 0,"aria-pressed":T?ag:void 0,sx:{cursor:"pointer",height:T?"100%":void 0,transition:"box-shadow 0.3s ease, border-color 0.12s ease",border:a=>T&&ag?`2px solid ${a.palette.primary.main}`:"2px solid transparent","&:hover":{boxShadow:3}},onClick:()=>{af.debug(`Server card clicked: ${a}`),Q()},children:[(0,d.jsxs)(aa.A,{sx:{pb:1},children:[(0,d.jsxs)(L.default,{sx:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",mb:1},children:[(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center",flex:1},children:[ai&&ah&&(0,d.jsx)(P.A,{checked:ag,onClick:a=>a.stopPropagation(),onChange:a=>ah(a.target.checked),size:"small",sx:{mr:1,p:.5}}),(0,d.jsx)(M.default,{variant:"h6",component:"h3",sx:{flex:1},children:a})]}),(0,d.jsxs)(L.default,{sx:{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:.5},children:[(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center",gap:.5},children:[am?.updateAvailable&&(0,d.jsx)(ab.A,{title:`Update available: ${(0,V.Fu)(am.localSha)} → ${(0,V.Fu)(am.remoteSha)}. Click to update.`,children:(0,d.jsx)(A.A,{icon:(0,d.jsx)(v.A,{}),label:"Update",color:"warning",size:"small",onClick:b=>{b.stopPropagation(),af.debug(`Update badge clicked for server: ${a}`),aA(!0)}})}),at?(0,d.jsx)(ab.A,{title:"FLUJO's built-in server — always available, cannot be edited or removed.",children:(0,d.jsx)(A.A,{label:"Built-in",color:"primary",size:"small"})}):(0,d.jsx)(F,{transport:C,size:"small"})]}),(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center"},children:["connected"===b&&(0,d.jsx)(h.A,{color:"success",sx:{mr:.5},fontSize:"small"}),"disconnected"===b&&(0,d.jsx)(i.A,{color:"action",sx:{mr:.5},fontSize:"small"}),"error"===b&&(0,d.jsx)(j.A,{color:"error",sx:{mr:.5},fontSize:"small"}),"requires_authentication"===b&&(0,d.jsx)(n.A,{color:"warning",sx:{mr:.5},fontSize:"small"}),("connecting"===b||"initialization"===b)&&(0,d.jsx)(w.default,{size:"small",color:"primary",sx:{mr:.5}}),(0,d.jsx)(M.default,{variant:"body2",color:aT,children:"requires_authentication"===b?"Requires Authentication":b})]})]})]}),(0,d.jsx)(M.default,{variant:"body2",color:"text.secondary",sx:{mb:1,fontSize:"0.875rem"},noWrap:!0,title:at?void 0:f,children:at?"FLUJO's own backend API — flow authoring, execution and server management as MCP tools.":f}),at&&!T&&(0,d.jsxs)(L.default,{sx:{mt:1,mb:1,p:1,borderRadius:1,border:"1px solid",borderColor:"divider"},onClick:a=>a.stopPropagation(),children:[(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center"},children:[(0,d.jsx)(q.A,{fontSize:"small",sx:{mr:.5,color:"primary.main"}}),(0,d.jsx)(ab.A,{title:"External MCP clients (Claude Code, Claude Desktop, Cursor, …) can drive FLUJO through this local endpoint.",children:(0,d.jsx)(M.default,{variant:"body2",sx:{fontWeight:500},children:"Exposed to external apps"})})]}),(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center",mt:.5},children:[(0,d.jsx)(M.default,{variant:"caption",sx:{flex:1,fontFamily:"monospace",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:"",children:""}),(0,d.jsx)(ab.A,{title:"Copy endpoint URL",children:(0,d.jsx)(ac.A,{size:"small",onClick:aR,children:(0,d.jsx)(s.A,{fontSize:"small"})})}),(0,d.jsx)(ab.A,{title:"Copy MCP server JSON",children:(0,d.jsx)(ac.A,{size:"small",onClick:aS,children:(0,d.jsx)(t.A,{fontSize:"small"})})})]})]}),!at&&!T&&(0,d.jsxs)(L.default,{sx:{mt:1,mb:1,p:1,borderRadius:1,border:"1px solid",borderColor:"divider"},onClick:a=>a.stopPropagation(),children:[(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center"},children:[(0,d.jsx)(q.A,{fontSize:"small",sx:{mr:.5,color:aL?"primary.main":"text.disabled"}}),(0,d.jsx)(ad.A,{checked:aL,onChange:a=>aP(a.target.checked),size:"small"}),(0,d.jsx)(ab.A,{title:"Re-expose this server's tools to external MCP clients (Claude Desktop, Cursor, …) at a local URL.",children:(0,d.jsx)(M.default,{variant:"body2",sx:{fontWeight:500},children:"Expose to external apps"})})]}),aL&&(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center",mt:.5},children:[(0,d.jsx)(M.default,{variant:"caption",sx:{flex:1,fontFamily:"monospace",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:"",children:""}),(0,d.jsx)(ab.A,{title:"Copy endpoint URL",children:(0,d.jsx)(ac.A,{size:"small",onClick:aR,children:(0,d.jsx)(s.A,{fontSize:"small"})})}),(0,d.jsx)(ab.A,{title:"Copy MCP server JSON",children:(0,d.jsx)(ac.A,{size:"small",onClick:aS,children:(0,d.jsx)(t.A,{fontSize:"small"})})})]})]}),!at&&!T&&(0,d.jsx)(L.default,{sx:{mt:1,mb:1,p:1,borderRadius:1,border:"1px solid",borderColor:"divider"},onClick:a=>a.stopPropagation(),children:(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center"},children:[(0,d.jsx)(r.A,{fontSize:"small",sx:{mr:.5,color:aN?"primary.main":"text.disabled"}}),(0,d.jsx)(ad.A,{checked:aN,onChange:a=>aQ(a.target.checked),size:"small"}),(0,d.jsx)(ab.A,{title:"Allow this server's tools to render interactive apps (MCP Apps / ui:// resources) in chat. Rendered read-only in a strict sandbox. Only enable for servers you trust.",children:(0,d.jsx)(M.default,{variant:"body2",sx:{fontWeight:500},children:"Render interactive apps"})})]})}),"error"===b&&(0,d.jsxs)(L.default,{sx:{mt:1,mb:1},children:[(0,d.jsxs)(L.default,{sx:{display:"flex",justifyContent:"space-between",alignItems:"center",mb:.5},children:[(0,d.jsx)(M.default,{variant:"body2",fontWeight:"medium",color:"error",children:"Error:"}),(0,d.jsx)(K.A,{size:"small",color:"primary",onClick:b=>{b.stopPropagation(),af.debug(`View full error clicked for server: ${a}`),aw(!0)},children:"View Full Error"})]}),(0,d.jsx)(L.default,{sx:{maxHeight:"80px",overflow:"auto",p:1,borderRadius:1,bgcolor:a=>aY("error.background"),color:a=>aY("error.text"),border:"1px solid",borderColor:a=>aY("error.border"),fontSize:"0.75rem",fontWeight:500,whiteSpace:"pre-wrap"},children:U||"Unknown error"})]}),"requires_authentication"===b&&!T&&(0,d.jsxs)(L.default,{sx:{mt:1,mb:1},children:[(0,d.jsx)(L.default,{sx:{display:"flex",justifyContent:"space-between",alignItems:"center",mb:1},children:(0,d.jsx)(M.default,{variant:"body2",fontWeight:"medium",color:"warning.main",children:"Authentication Required"})}),(0,d.jsxs)(K.A,{variant:"contained",color:"warning",size:"small",startIcon:(0,d.jsx)(o.A,{}),onClick:async b=>{if(b.stopPropagation(),af.debug(`Authenticate button clicked for server: ${a}`),S)S();else try{let b=await fetch("/api/oauth/initiate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({serverName:a})});if(!b.ok){let a=await b.json();throw Error(a.error||"Failed to initiate OAuth")}let{authorizationUrl:d,alreadyAuthorized:e}=await b.json();if(e||!d){af.info(`Server ${a} already authorized, no popup needed`),a$();return}let{openOAuthPopup:f}=await c.e(558).then(c.bind(c,60558));await f({url:d,windowName:`oauth_${a}`,onSuccess:b=>{af.info(`OAuth authentication successful for ${a}`,b),af.info(`Automatically restarting server ${a} after OAuth completion`),a$()},onError:b=>{af.error(`OAuth authentication failed for ${a}`,b),aE("OAuth authentication failed"),aG("error"),aC(!0)}})}catch(b){af.error(`Failed to start OAuth authentication for ${a}`,b),aE("Failed to start OAuth authentication"),aG("error"),aC(!0)}},sx:{width:"100%"},children:["Authenticate with ",a]})]})]}),!at&&!T&&(0,d.jsxs)(ae.A,{sx:{justifyContent:"space-between",px:2,py:1},children:[(0,d.jsxs)(L.default,{sx:{display:"flex",alignItems:"center"},children:[(0,d.jsx)(ad.A,{checked:B,onClick:a=>a.stopPropagation(),onChange:b=>{af.debug(`Server ${a} toggle changed to: ${b.target.checked}`),D(b.target.checked)},color:"primary",size:"small"}),(0,d.jsx)(M.default,{variant:"body2",sx:{ml:.5,fontWeight:500,color:B?"primary.main":"text.secondary"},children:B?"Enabled":"Disabled"}),B&&(0,d.jsx)(ab.A,{title:"Restart server",children:(0,d.jsx)(ac.A,{size:"small",onClick:b=>{b.stopPropagation(),af.debug(`Restart button clicked for server: ${a}`),a$()},sx:{ml:1},children:(0,d.jsx)(k.A,{fontSize:"small"})})})]}),(0,d.jsxs)(L.default,{children:[(0,d.jsx)(ab.A,{title:"Retry connection",children:(0,d.jsx)(ac.A,{color:"primary",onClick:c=>{c.stopPropagation(),af.debug(`Retry button clicked for server: ${a}`),aU&&clearTimeout(aU),aI(!0),E();let d=setTimeout(()=>{"connecting"!==b&&"initialization"!==b&&aI(!1),aV(null)},1e4);aV(d)},disabled:aH,size:"small",children:aH?(0,d.jsx)(w.default,{size:"small",color:"primary"}):(0,d.jsx)(k.A,{})})}),"streamable"===C&&aj&&(0,d.jsx)(ab.A,{title:"Reset OAuth tokens",children:(0,d.jsx)(ac.A,{color:"warning",onClick:aW,disabled:aJ,size:"small",children:aJ?(0,d.jsx)(w.default,{size:"small",color:"primary"}):(0,d.jsx)(p.A,{})})}),as&&(0,d.jsx)(ab.A,{title:aq?`Folder: ${aq}`:"Move to folder",children:(0,d.jsx)(ac.A,{color:aq?"primary":"default",onClick:a=>{a.stopPropagation(),ay(a.currentTarget)},size:"small",children:(0,d.jsx)(u.A,{})})}),(0,d.jsx)(ab.A,{title:"Edit server",children:(0,d.jsx)(ac.A,{color:"primary",onClick:a=>{a.stopPropagation(),R()},size:"small",children:(0,d.jsx)(l.A,{})})}),(0,d.jsx)(ab.A,{title:"Delete server",children:(0,d.jsx)(ac.A,{color:"error",onClick:a=>{a.stopPropagation(),O()},size:"small",children:(0,d.jsx)(m.A,{})})})]})]}),as&&(0,d.jsx)(x.A,{anchorEl:ax,open:!!ax,currentFolder:aq,folders:ar,onClose:()=>ay(null),onAssign:a=>as(a)}),(0,d.jsxs)(G.A,{open:av,onClose:()=>{af.debug(`Error modal closed for server: ${a}`),aw(!1)},maxWidth:"md",fullWidth:!0,onClick:a=>a.stopPropagation(),children:[(0,d.jsxs)(H.A,{component:"div",children:["Error Details for ",a]}),(0,d.jsxs)(I.A,{children:[(0,d.jsx)(L.default,{sx:{p:2,borderRadius:1,bgcolor:a=>aY("error.background"),color:a=>aY("error.text"),border:"1px solid",borderColor:a=>aY("error.border"),fontFamily:"monospace",fontSize:"0.875rem",fontWeight:500,whiteSpace:"pre-wrap",overflow:"auto",maxHeight:"300px",mb:2},children:U||"Unknown error"}),W&&(0,d.jsxs)(L.default,{sx:{mt:2},children:[(0,d.jsx)(M.default,{variant:"h6",gutterBottom:!0,children:"Stderr Output:"}),(0,d.jsx)(L.default,{sx:{p:2,borderRadius:1,bgcolor:"background.paper",border:"1px solid",borderColor:"divider",fontFamily:"monospace",fontSize:"0.875rem",whiteSpace:"pre-wrap",overflow:"auto",maxHeight:"300px"},children:W})]})]}),(0,d.jsxs)(J.A,{children:[(0,d.jsx)(K.A,{onClick:()=>aw(!1),children:"Close"}),(0,d.jsx)(K.A,{onClick:()=>{let b=[U||"Unknown error",W?`
3
-
4
- Stderr Output:
5
- ${W}`:""].join("");navigator.clipboard.writeText(b),af.debug(`Error copied to clipboard for server: ${a}`),aE("Error message copied to clipboard"),aG("success"),aC(!0)},color:"primary",children:"Copy to Clipboard"})]})]}),am&&(0,d.jsx)(Y,{open:az,onClose:()=>aA(!1),serverName:a,rootPath:f,installCommand:an,buildCommand:ao,enabled:B,updateInfo:am,onToggle:D,onUpdated:ap}),(0,d.jsx)(Z.A,{open:aB,autoHideDuration:3e3,onClose:()=>aC(!1),anchorOrigin:{vertical:"bottom",horizontal:"center"},children:(0,d.jsx)(N.A,{onClose:()=>aC(!1),severity:aF,sx:{width:"100%"},children:aD||"Error message copied to clipboard"})})]})}},50846:(a,b,c)=>{c.d(b,{h:()=>i});var d=c(13516);let e={VERBOSE:-1,DEBUG:0,INFO:1,WARN:2,ERROR:3},f="number"==typeof d.G.LOG_LEVEL?d.G.LOG_LEVEL:e.ERROR;function g(a,b=0){if(b>6)return String(a);if(!(a instanceof Error))return a;let c={name:a.name,message:a.message};for(let d of Object.getOwnPropertyNames(a)){if("name"===d||"message"===d)continue;let e=a[d];"function"!=typeof e&&("stack"===d?c.stack=e:"cause"===d?c.cause=g(e,b+1):"errors"===d&&Array.isArray(e)?c.errors=e.map(a=>g(a,b+1)):c[d]=e)}return c}function h(a,b,c,d,h){if(a>=("number"==typeof h?h:f)){if("function"==typeof d)try{d=d()}catch{d="[lazy log data threw]"}let f=new Date().toISOString(),h=`[${f}] [${b}]`,i=`${h} ${c}`;if(void 0!==d)if(d instanceof Error||"object"==typeof d)try{let a=d instanceof Error?g(d):d,b=JSON.stringify(a,(a,b)=>b instanceof Error?g(b):b,2);i+=`:
6
- ${b}`}catch(a){i+=": [Object cannot be stringified]"}else i+=`: ${d}`;switch(a){case e.VERBOSE:console.debug(`[VERBOSE] ${i}`);break;case e.DEBUG:console.debug(i);break;case e.INFO:console.info(i);break;case e.WARN:console.warn(i);break;case e.ERROR:console.error(i);break;default:console.log(i)}}}function i(a,b){let c,d=((c=a.replace(/^src\//,"")).startsWith("/")&&(c=c.substring(1)),c);return{verbose:(a,c)=>{h(e.VERBOSE,d,a,c,b)},debug:(a,c)=>{h(e.DEBUG,d,a,c,b)},info:(a,c)=>{h(e.INFO,d,a,c,b)},warn:(a,c)=>{h(e.WARN,d,a,c,b)},error:(a,c)=>{h(e.ERROR,d,a,c,b)}}}},53455:(a,b,c)=>{c.d(b,{Fu:()=>i,M8:()=>f,Qv:()=>g,Qz:()=>h});let d=(0,c(19815).h)("frontend/components/mcp/MCPServerManager/utils/serverUpdates"),e=new Map;async function f(a,b=!1){let c=Date.now(),g={},h=[];for(let d of new Set(a.filter(Boolean))){let a=e.get(d);!b&&a&&c-a.at<6e5?g[d]=a.info:h.push(d)}if(h.length>0)try{let a=await fetch("/api/git",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"checkUpdatesBatch",paths:h})}),b=await a.json();if(a.ok&&b.results)for(let[a,d]of Object.entries(b.results))e.set(a,{at:c,info:d}),g[a]=d;else d.warn("Batch update check failed",b.error)}catch(a){d.warn("Batch update check request failed",a)}return g}async function g(a){try{let b=await fetch("/api/git",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"pullUpdates",savePath:a})}),c=await b.json();if(!b.ok)return{success:!1,error:c.error||"Failed to pull updates"};return{success:!0,oldSha:c.oldSha,newSha:c.newSha,updated:c.updated}}catch(a){return{success:!1,error:a.message||"Failed to pull updates"}}}async function h(a,b,c){let e=a.match(/github\.com[:/]([^/]+)\/([^/]+?)(?:\.git)?\/?$/i);if(!e)return null;try{let a=await fetch(`https://api.github.com/repos/${e[1]}/${e[2]}/compare/${b}...${c}`);if(!a.ok)return null;let d=await a.json(),f=Array.isArray(d.commits)?d.commits:[];return{behindBy:"number"==typeof d.total_commits?d.total_commits:null,commits:f.slice(-10).reverse().map(a=>({sha:(a.sha||"").slice(0,7),message:(a.commit?.message||"").split("\n")[0]}))}}catch(a){return d.debug("GitHub compare preview failed (non-fatal)",a),null}}function i(a){return a?a.slice(0,7):""}},61160:(a,b,c)=>{c.d(b,{mO:()=>f,rI:()=>g});var d=c(7329);let e=["stdio","websocket","sse","streamable"];function f(a,b){switch(b){case"name-asc":case"name-desc":return(0,d.po)(a.name);case"status-connected":case"status-disconnected":{let b=a.status;if("connected"===b)return{key:"status:connected",label:"Connected"};if("error"===b)return{key:"status:error",label:"Error"};if("requires_authentication"===b)return{key:"status:auth",label:"Requires authentication"};return{key:"status:disconnected",label:"Disconnected"}}case"transport":{let b=a.transport||"unknown";return{key:`transport:${b}`,label:({stdio:"Stdio",websocket:"WebSocket",sse:"SSE",streamable:"Streamable HTTP"})[b]||b}}default:return{key:"all",label:"All servers"}}}function g(a,b){return[...a].sort((a,c)=>{switch(b){case"name-asc":return a.name.localeCompare(c.name);case"name-desc":return c.name.localeCompare(a.name);case"status-connected":if("connected"===a.status&&"connected"!==c.status)return -1;if("connected"!==a.status&&"connected"===c.status)return 1;return a.name.localeCompare(c.name);case"status-disconnected":if("disconnected"===a.status&&"disconnected"!==c.status)return -1;if("disconnected"!==a.status&&"disconnected"===c.status)return 1;return a.name.localeCompare(c.name);case"transport":{let b=e.indexOf(a.transport??""),d=e.indexOf(c.transport??"");if(b!==d)return b-d;return a.name.localeCompare(c.name)}default:return 0}})}},84040:(a,b,c)=>{c.d(b,{Ic:()=>g});var d=c(32631);let e=(0,c(19815).h)("frontend/utils/theme"),f={light:{background:"#FFFFFF",foreground:"#2C3E50",paperBackground:"#F5F6FA",textSecondary:"#7F8C8D",border:"#e5e7eb",heading:"#111",text:"#333",secondaryText:"#666",error:{background:"#fef2f2",border:"#fecaca",text:"#dc2626"}},dark:{background:"#1a1a1a",foreground:"#f0f0f0",paperBackground:"#2a2a2a",textSecondary:"#aaaaaa",border:"#3a3a3a",heading:"#f8f8f8",text:"#f0f0f0",secondaryText:"#aaa",error:{background:"#3a2222",border:"#5a3333",text:"#f87171"}}};function g(){let{isDarkMode:a}=(0,d.D)();return e.debug(`useThemeUtils called with isDarkMode: ${a}`),{getThemeValue:(b,c)=>a?c:b,getThemeColor:b=>{let c=b.split("."),d=f[a?"dark":"light"];for(let a of c)if(!d||"object"!=typeof d||!(a in d))return e.warn(`Theme color path not found: ${b}`),"";else d=d[a];return d},colors:a?f.dark:f.light,isDarkMode:a}}}};
@@ -1 +0,0 @@
1
- "use strict";exports.id=3291,exports.ids=[3291],exports.modules={423:(a,b,c)=>{c.d(b,{A:()=>s});var d=c(38301),e=c(43249),f=c(2783),g=c(18168),h=c(68333),i=c(6636),j=c(29565),k=c(33105);function l(a){return(0,k.Ay)("MuiCardActionArea",a)}let m=(0,j.A)("MuiCardActionArea",["root","focusVisible","focusHighlight"]);var n=c(14328),o=c(20385),p=c(21124);let q=(0,g.Ay)(n.A,{name:"MuiCardActionArea",slot:"Root",overridesResolver:(a,b)=>b.root})((0,h.A)(({theme:a})=>({display:"block",textAlign:"inherit",borderRadius:"inherit",width:"100%",[`&:hover .${m.focusHighlight}`]:{opacity:(a.vars||a).palette.action.hoverOpacity,"@media (hover: none)":{opacity:0}},[`&.${m.focusVisible} .${m.focusHighlight}`]:{opacity:(a.vars||a).palette.action.focusOpacity}}))),r=(0,g.Ay)("span",{name:"MuiCardActionArea",slot:"FocusHighlight",overridesResolver:(a,b)=>b.focusHighlight})((0,h.A)(({theme:a})=>({overflow:"hidden",pointerEvents:"none",position:"absolute",top:0,right:0,bottom:0,left:0,borderRadius:"inherit",opacity:0,backgroundColor:"currentcolor",transition:a.transitions.create("opacity",{duration:a.transitions.duration.short})}))),s=d.forwardRef(function(a,b){let c=(0,i.b)({props:a,name:"MuiCardActionArea"}),{children:d,className:g,focusVisibleClassName:h,slots:j={},slotProps:k={},...m}=c,n=(a=>{let{classes:b}=a;return(0,f.A)({root:["root"],focusHighlight:["focusHighlight"]},l,b)})(c),s={slots:j,slotProps:k},[t,u]=(0,o.A)("root",{elementType:q,externalForwardedProps:{...s,...m},shouldForwardComponentProp:!0,ownerState:c,ref:b,className:(0,e.A)(n.root,g),additionalProps:{focusVisibleClassName:(0,e.A)(h,n.focusVisible)}}),[v,w]=(0,o.A)("focusHighlight",{elementType:r,externalForwardedProps:s,ownerState:c,ref:b,className:n.focusHighlight});return(0,p.jsxs)(t,{...u,children:[d,(0,p.jsx)(v,{...w})]})})},2117:(a,b,c)=>{c.d(b,{A:()=>i});var d=c(55511);let e={randomUUID:d.randomUUID},f=new Uint8Array(256),g=f.length,h=[];for(let a=0;a<256;++a)h.push((a+256).toString(16).slice(1));let i=function(a,b,c){if(e.randomUUID&&!b&&!a)return e.randomUUID();let i=(a=a||{}).random??a.rng?.()??(g>f.length-16&&((0,d.randomFillSync)(f),g=0),f.slice(g,g+=16));if(i.length<16)throw Error("Random bytes length must be >= 16");if(i[6]=15&i[6]|64,i[8]=63&i[8]|128,b){if((c=c||0)<0||c+16>b.length)throw RangeError(`UUID byte range ${c}:${c+15} is out of buffer bounds`);for(let a=0;a<16;++a)b[c+a]=i[a];return b}return function(a,b=0){return(h[a[b+0]]+h[a[b+1]]+h[a[b+2]]+h[a[b+3]]+"-"+h[a[b+4]]+h[a[b+5]]+"-"+h[a[b+6]]+h[a[b+7]]+"-"+h[a[b+8]]+h[a[b+9]]+"-"+h[a[b+10]]+h[a[b+11]]+h[a[b+12]]+h[a[b+13]]+h[a[b+14]]+h[a[b+15]]).toLowerCase()}(i)}},7499:(a,b,c)=>{c.d(b,{A:()=>t});var d=c(38301),e=c(43249),f=c(75575),g=c(2783),h=c(37489),i=c(14328),j=c(6638),k=c(18168),l=c(68333),m=c(54716),n=c(6636),o=c(35133),p=c(73032),q=c(73284),r=c(21124);let s=(0,k.Ay)(i.A,{name:"MuiToggleButton",slot:"Root",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[b.root,b[`size${(0,j.A)(c.size)}`]]}})((0,l.A)(({theme:a})=>({...a.typography.button,borderRadius:(a.vars||a).shape.borderRadius,padding:11,border:`1px solid ${(a.vars||a).palette.divider}`,color:(a.vars||a).palette.action.active,[`&.${o.A.disabled}`]:{color:(a.vars||a).palette.action.disabled,border:`1px solid ${(a.vars||a).palette.action.disabledBackground}`},"&:hover":{textDecoration:"none",backgroundColor:a.vars?`rgba(${a.vars.palette.text.primaryChannel} / ${a.vars.palette.action.hoverOpacity})`:(0,h.X4)(a.palette.text.primary,a.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:"transparent"}},variants:[{props:{color:"standard"},style:{[`&.${o.A.selected}`]:{color:(a.vars||a).palette.text.primary,backgroundColor:a.vars?`rgba(${a.vars.palette.text.primaryChannel} / ${a.vars.palette.action.selectedOpacity})`:(0,h.X4)(a.palette.text.primary,a.palette.action.selectedOpacity),"&:hover":{backgroundColor:a.vars?`rgba(${a.vars.palette.text.primaryChannel} / calc(${a.vars.palette.action.selectedOpacity} + ${a.vars.palette.action.hoverOpacity}))`:(0,h.X4)(a.palette.text.primary,a.palette.action.selectedOpacity+a.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:a.vars?`rgba(${a.vars.palette.text.primaryChannel} / ${a.vars.palette.action.selectedOpacity})`:(0,h.X4)(a.palette.text.primary,a.palette.action.selectedOpacity)}}}}},...Object.entries(a.palette).filter((0,m.A)()).map(([b])=>({props:{color:b},style:{[`&.${o.A.selected}`]:{color:(a.vars||a).palette[b].main,backgroundColor:a.vars?`rgba(${a.vars.palette[b].mainChannel} / ${a.vars.palette.action.selectedOpacity})`:(0,h.X4)(a.palette[b].main,a.palette.action.selectedOpacity),"&:hover":{backgroundColor:a.vars?`rgba(${a.vars.palette[b].mainChannel} / calc(${a.vars.palette.action.selectedOpacity} + ${a.vars.palette.action.hoverOpacity}))`:(0,h.X4)(a.palette[b].main,a.palette.action.selectedOpacity+a.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:a.vars?`rgba(${a.vars.palette[b].mainChannel} / ${a.vars.palette.action.selectedOpacity})`:(0,h.X4)(a.palette[b].main,a.palette.action.selectedOpacity)}}}}})),{props:{fullWidth:!0},style:{width:"100%"}},{props:{size:"small"},style:{padding:7,fontSize:a.typography.pxToRem(13)}},{props:{size:"large"},style:{padding:15,fontSize:a.typography.pxToRem(15)}}]}))),t=d.forwardRef(function(a,b){var c;let{value:h,...i}=d.useContext(p.A),k=d.useContext(q.A),l=(0,f.A)({...i,selected:(c=a.value,void 0!==h&&void 0!==c&&(Array.isArray(h)?h.includes(c):c===h))},a),m=(0,n.b)({props:l,name:"MuiToggleButton"}),{children:t,className:u,color:v="standard",disabled:w=!1,disableFocusRipple:x=!1,fullWidth:y=!1,onChange:z,onClick:A,selected:B,size:C="medium",value:D,...E}=m,F={...m,color:v,disabled:w,disableFocusRipple:x,fullWidth:y,size:C},G=(a=>{let{classes:b,fullWidth:c,selected:d,disabled:e,size:f,color:h}=a,i={root:["root",d&&"selected",e&&"disabled",c&&"fullWidth",`size${(0,j.A)(f)}`,h]};return(0,g.A)(i,o.J,b)})(F);return(0,r.jsx)(s,{className:(0,e.A)(i.className,G.root,u,k||""),disabled:w,focusRipple:!x,ref:b,onClick:a=>{A&&(A(a,D),a.defaultPrevented)||z&&z(a,D)},onChange:z,value:D,ownerState:F,"aria-pressed":B,...E,children:t})})},29277:(a,b,c)=>{c.d(b,{A:()=>e});var d=c(38301);function e(a){return d.Children.toArray(a).filter(a=>d.isValidElement(a))}},35133:(a,b,c)=>{c.d(b,{A:()=>g,J:()=>f});var d=c(29565),e=c(33105);function f(a){return(0,e.Ay)("MuiToggleButton",a)}let g=(0,d.A)("MuiToggleButton",["root","disabled","selected","standard","primary","secondary","sizeSmall","sizeMedium","sizeLarge","fullWidth"])},48317:(a,b,c)=>{c.d(b,{A:()=>u});var d=c(38301),e=c(43249),f=c(2783),g=c(29277),h=c(18168),i=c(68333),j=c(6636),k=c(6638),l=c(29565),m=c(33105);function n(a){return(0,m.Ay)("MuiToggleButtonGroup",a)}let o=(0,l.A)("MuiToggleButtonGroup",["root","selected","horizontal","vertical","disabled","grouped","groupedHorizontal","groupedVertical","fullWidth","firstButton","lastButton","middleButton"]);var p=c(73032),q=c(73284),r=c(35133),s=c(21124);let t=(0,h.Ay)("div",{name:"MuiToggleButtonGroup",slot:"Root",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[{[`& .${o.grouped}`]:b.grouped},{[`& .${o.grouped}`]:b[`grouped${(0,k.A)(c.orientation)}`]},{[`& .${o.firstButton}`]:b.firstButton},{[`& .${o.lastButton}`]:b.lastButton},{[`& .${o.middleButton}`]:b.middleButton},b.root,"vertical"===c.orientation&&b.vertical,c.fullWidth&&b.fullWidth]}})((0,i.A)(({theme:a})=>({display:"inline-flex",borderRadius:(a.vars||a).shape.borderRadius,variants:[{props:{orientation:"vertical"},style:{flexDirection:"column",[`& .${o.grouped}`]:{[`&.${o.selected} + .${o.grouped}.${o.selected}`]:{borderTop:0,marginTop:0}},[`& .${o.firstButton},& .${o.middleButton}`]:{borderBottomLeftRadius:0,borderBottomRightRadius:0},[`& .${o.lastButton},& .${o.middleButton}`]:{marginTop:-1,borderTop:"1px solid transparent",borderTopLeftRadius:0,borderTopRightRadius:0},[`& .${o.lastButton}.${r.A.disabled},& .${o.middleButton}.${r.A.disabled}`]:{borderTop:"1px solid transparent"}}},{props:{fullWidth:!0},style:{width:"100%"}},{props:{orientation:"horizontal"},style:{[`& .${o.grouped}`]:{[`&.${o.selected} + .${o.grouped}.${o.selected}`]:{borderLeft:0,marginLeft:0}},[`& .${o.firstButton},& .${o.middleButton}`]:{borderTopRightRadius:0,borderBottomRightRadius:0},[`& .${o.lastButton},& .${o.middleButton}`]:{marginLeft:-1,borderLeft:"1px solid transparent",borderTopLeftRadius:0,borderBottomLeftRadius:0},[`& .${o.lastButton}.${r.A.disabled},& .${o.middleButton}.${r.A.disabled}`]:{borderLeft:"1px solid transparent"}}}]}))),u=d.forwardRef(function(a,b){let c=(0,j.b)({props:a,name:"MuiToggleButtonGroup"}),{children:h,className:i,color:l="standard",disabled:m=!1,exclusive:o=!1,fullWidth:r=!1,onChange:u,orientation:v="horizontal",size:w="medium",value:x,...y}=c,z={...c,disabled:m,fullWidth:r,orientation:v,size:w},A=(a=>{let{classes:b,orientation:c,fullWidth:d,disabled:e}=a,g={root:["root",c,d&&"fullWidth"],grouped:["grouped",`grouped${(0,k.A)(c)}`,e&&"disabled"],firstButton:["firstButton"],lastButton:["lastButton"],middleButton:["middleButton"]};return(0,f.A)(g,n,b)})(z),B=d.useCallback((a,b)=>{let c;if(!u)return;let d=x&&x.indexOf(b);x&&d>=0?(c=x.slice()).splice(d,1):c=x?x.concat(b):[b],u(a,c)},[u,x]),C=d.useCallback((a,b)=>{u&&u(a,x===b?null:b)},[u,x]),D=d.useMemo(()=>({className:A.grouped,onChange:o?C:B,value:x,size:w,fullWidth:r,color:l,disabled:m}),[A.grouped,o,C,B,x,w,r,l,m]),E=(0,g.A)(h),F=E.length;return(0,s.jsx)(t,{role:"group",className:(0,e.A)(A.root,i),ref:b,ownerState:z,...y,children:(0,s.jsx)(p.A.Provider,{value:D,children:E.map((a,b)=>(0,s.jsx)(q.A.Provider,{value:(a=>{let b=0===a,c=a===F-1;return b&&c?"":b?A.firstButton:c?A.lastButton:A.middleButton})(b),children:a},b))})})})},73032:(a,b,c)=>{c.d(b,{A:()=>d});let d=c(38301).createContext({})},73284:(a,b,c)=>{c.d(b,{A:()=>d});let d=c(38301).createContext(void 0)},96955:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(27080),e=c(21124);let f=(0,d.A)((0,e.jsx)("path",{d:"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2m0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2"}),"MoreVert")}};
@@ -1,81 +0,0 @@
1
- "use strict";exports.id=4637,exports.ids=[4637],exports.modules={74637:(a,b,c)=>{let d;c.d(b,{internalCallTool:()=>bm,internalToolDefinitions:()=>aS});var e=c(33873),f=c.n(e),g=c(29021),h=c(79646),i=c(18230);let j=(0,i.h)("utils/process/killProcessTree");var k=c(11659),l=c(12763),m=c(50010),n=c(35432),o=c(52823),p=c(89850),q=c(8336),r=c(78606);function s(a,b,c,d){return"number"!=typeof a||Number.isNaN(a)?d:Math.max(b,Math.min(c,Math.floor(a)))}let t={type:"arrowclosed",width:20,height:20,color:"#1976d2"},u={stroke:"#1976d2",strokeWidth:2},v={type:"arrowclosed",width:20,height:20,color:"#009688"},w={stroke:"#009688",strokeWidth:2},x=new Set(["full-history","latest-message","isolated"]),y=new Set(["steps","final-only"]),z=new Set(["full-conversation","latest-message"]);function A(a){let b=(0,q.A$)(a);if(0===b.length)return{text:a,stripped:!1};let c="",d=0;for(let e of b)c+=a.slice(d,e.index)+e.name,d=e.index+e.fullMatch.length;return{text:c+=a.slice(d),stripped:!0}}function B(a,b){if(b.some(b=>b.id===a))return a;let c=a.toLowerCase(),d=b.find(a=>a.name.toLowerCase()===c);return d?d.id:null}var C=c(54898),D=c(82464);let E=(0,i.h)("backend/services/flow/generationContext");function F(a,b){let c=String(a).replace(/\s+/g," ").trim();return c.length<=b?c:`${c.slice(0,b).trimEnd()}…`}async function G(){let a=await l.modelService.loadModels(),b=a.map(a=>({id:a.id,name:a.name,...a.displayName?{displayName:a.displayName}:{},...a.description?{description:F(a.description,100)}:{}})),c=[],d={};try{let a=await D.mcpService.loadServerConfigs();if(Array.isArray(a))for(let b of a){if(b.disabled)continue;let a=!1;try{let c=await D.mcpService.getServerStatus(b.name);a=c?.status==="connected"}catch(a){E.debug(`getServerStatus failed for ${b.name}; listing name only`,a)}if(!a){c.push({name:b.name,connected:!1});continue}let{tools:e}=await D.mcpService.listServerTools(b.name),f=(e??[]).filter(a=>a.name).map(a=>({name:a.name,...a.description?{description:F(a.description,100)}:{}}));d[b.name]=f.map(a=>a.name),c.push({name:b.name,connected:!0,tools:f})}}catch(a){E.warn("Could not load MCP servers for the authoring context",a)}let e=[];try{e=await k.flowService.loadFlows()}catch(a){E.warn("Could not load flows for the authoring context",a)}let f={models:b,servers:c,flows:e.map(a=>({id:a.id,name:a.name,...a.description?{description:F(a.description,300)}:{},nodeCount:a.nodes?.length??0}))};return{blocks:f,compile:{models:a.map(a=>({id:a.id,name:a.name,displayName:a.displayName})),servers:c.map(a=>({name:a.name})),serverTools:d,flows:e.map(a=>({id:a.id,name:a.name}))},catalog:function(a){let b=[];for(let c of(b.push("AVAILABLE MODELS (reference by id or name):"),0===a.models.length&&b.push(" (none configured)"),a.models)){let a=c.displayName&&c.displayName!==c.name?`"${c.displayName}" (${c.name})`:c.name,d=c.description?` — ${c.description}`:"";b.push(` - id: ${c.id} — ${a}${d}`)}for(let c of(b.push("",'AVAILABLE MCP SERVERS (attach to process nodes via "servers"):'),0===a.servers.length&&b.push(" (none configured)"),a.servers)){if(!c.connected){b.push(` - ${c.name} (offline — tools unknown; may still be used)`);continue}b.push(` - ${c.name}:`);let a=(c.tools??[]).slice(0,20);for(let c of a){let a=c.description?` — ${c.description}`:"";b.push(` - ${c.name}${a}`)}let d=(c.tools?.length??0)-a.length;d>0&&b.push(` - …and ${d} more`)}for(let c of(b.push("",'EXISTING FLOWS (usable as subflow targets via "flow"):'),0===a.flows.length&&b.push(" (none)"),a.flows.slice(0,15))){let a=c.description?` — ${c.description}`:` — ${c.nodeCount} nodes`;b.push(` - "${c.name}"${a}`)}return a.flows.length>15&&b.push(` - …and ${a.flows.length-15} more`),b.join("\n")}(f),validatorServers:c.map(a=>({name:a.name,status:a.connected?"connected":"disconnected"}))}}let H=(0,i.h)("backend/services/flow/compileFlow");async function I(a,b={}){if(!a||"object"!=typeof a||Array.isArray(a))return{success:!1,error:"The spec must be a JSON object (a FlowSpec)",statusCode:400};let c=await G(),d=c.compile;if(b.updateFlowId){let a=d.flows??[];if(!a.some(a=>a.id===b.updateFlowId))return{success:!1,error:`No flow with id "${b.updateFlowId}" to update`,statusCode:404};d={...d,flows:a.filter(a=>a.id!==b.updateFlowId)}}let e=function(a,b={},c={}){let d=[],e=(a,b,c)=>d.push({severity:"error",code:a,message:b,nodeKey:c}),f=(a,b,c)=>d.push({severity:"warning",code:a,message:b,nodeKey:c}),g=b.models??[],h=new Set((b.servers??[]).map(a=>a.name)),i=b.serverTools??{},j=s(c.maxDepth,0,3,3),k=s(c.maxFlows,1,8,8),l=[],m=[...(b.flows??[]).map(a=>a.name)],n=[],o=0;var q=function a(d,q,C){let D=Array.isArray(d?.nodes)?d.nodes:[],E=Array.isArray(d?.edges)?d.edges:[],G=function(a,b){let c=(a??"").trim().replace(/[^\w-]+/g,"_").replace(/^_+|_+$/g,"");c||(c="generated_flow");let d=new Set(b.map(a=>a.toLowerCase()));if(!d.has(c.toLowerCase()))return c;for(let a=2;;a++){let b=`${c}_${a}`;if(!d.has(b.toLowerCase()))return b}}(d?.name,m);m.push(G),o++;let H=(0,p.A)(),I=[...C,G],J=new Map,K=[],L=[];for(let c of D){let d=c?.key;if(!d||"string"!=typeof d){e("node-missing-key",'A node is missing its "key" — every node needs a unique key.');continue}if(J.has(d)){e("node-duplicate-key",`Duplicate node key "${d}" — keys must be unique; the later node was dropped.`,d);continue}let l=c.type;if("mcp"===l){e("mcp-node-not-allowed",`Node "${d}": do not emit "mcp" nodes — attach servers to a process node via its "servers" list instead.`,d);continue}if("start"!==l&&"process"!==l&&"finish"!==l&&"subflow"!==l&&"resource"!==l&&"signal"!==l){e("unknown-node-type",`Node "${d}" has unknown type "${String(l)}".`,d);continue}let m={},r="string"==typeof c.prompt?c.prompt:void 0;if("start"===l){let{text:a,stripped:b}=A(r??"");b&&f("pill-stripped",`Node "${d}": binding pills are not supported in generated prompts and were replaced with plain names.`,d),m.promptTemplate=a}else if("process"===l){let{text:a,stripped:b}=A(r??"");if(b&&f("pill-stripped",`Node "${d}": binding pills are not supported in generated prompts and were replaced with plain names.`,d),m.promptTemplate=a,c.model){let a=function(a,b){if(b.some(b=>b.id===a))return a;let c=a.toLowerCase(),d=b.find(a=>a.displayName?.toLowerCase()===c);if(d)return d.id;let e=b.find(a=>a.name?.toLowerCase()===c);return e?e.id:null}(c.model,g);a?m.boundModel=a:(m.boundModel=c.model,f("model-unresolved",`Node "${d}": model "${c.model}" does not match any configured model (by id, display name, or name).`,d))}void 0!==c.inputMode&&(x.has(c.inputMode)?(m.inputMode=c.inputMode,"isolated"===c.inputMode&&"string"==typeof c.isolatedPrompt&&(m.isolatedPrompt=c.isolatedPrompt)):f("invalid-input-mode",`Node "${d}": inputMode "${String(c.inputMode)}" is not valid (full-history | latest-message | isolated); omitted.`,d)),void 0!==c.outputMode&&(z.has(c.outputMode)?m.outputMode=c.outputMode:f("invalid-output-mode",`Node "${d}": outputMode "${String(c.outputMode)}" is not valid on a process node (full-conversation | latest-message); omitted.`,d)),void 0!==c.maxTurns&&("number"!=typeof c.maxTurns||Number.isNaN(c.maxTurns)?f("invalid-max-turns",`Node "${d}": maxTurns "${String(c.maxTurns)}" is not a number; omitted.`,d):m.maxTurns=s(c.maxTurns,1,1e3,1)),"boolean"==typeof c.excludeModelPrompt&&(m.excludeModelPrompt=c.excludeModelPrompt),"boolean"==typeof c.excludeStartNodePrompt&&(m.excludeStartNodePrompt=c.excludeStartNodePrompt),"boolean"==typeof c.excludeSystemPrompt&&(m.excludeSystemPrompt=c.excludeSystemPrompt),Array.isArray(c.allowedTools)&&(m.allowedTools=c.allowedTools.filter(a=>"string"==typeof a&&a)),"string"==typeof c.captureVariable&&c.captureVariable.trim()&&(m.captureVariable=c.captureVariable.trim()),"string"==typeof c.captureResource&&c.captureResource.trim()&&(m.captureResource=c.captureResource.trim()),"string"==typeof c.captureKv&&c.captureKv.trim()&&(m.captureKv=c.captureKv.trim())}else if("subflow"===l){if(function(c,d,g,h,i){let l=Array.isArray(c.parallelFlows)&&c.parallelFlows.length>0,m=Array.isArray(c.parallelSubflowSpecs)&&c.parallelSubflowSpecs.length>0,p="string"==typeof c.parallelFlowsVariable?c.parallelFlowsVariable.trim():"";if([void 0!==c.flow&&null!==c.flow?"flow":null,void 0!==c.subflowSpec&&null!==c.subflowSpec?"subflowSpec":null,l?"parallelFlows":null,m?"parallelSubflowSpecs":null,void 0!==c.generateSubflow&&null!==c.generateSubflow?"generateSubflow":null].filter(Boolean).length>1&&f("subflow-multiple-sources",`Node "${d}": a subflow node should have only one target source ("flow", "subflowSpec", "parallelFlows", "parallelSubflowSpecs", or "generateSubflow"); applying precedence flow > subflowSpec > parallelFlows > parallelSubflowSpecs > generateSubflow.`,d),!0===c.mapOverList){let a=void 0!==c.flow&&null!==c.flow||void 0!==c.subflowSpec&&null!==c.subflowSpec;(l||m)&&e("subflow-map-and-parallel",`Node "${d}": "mapOverList" runs a SINGLE child once per item and cannot be combined with "parallelFlows"/"parallelSubflowSpecs".`,d),a?(i.mapOverList=!0,void 0!==c.itemSplit&&("json-array"===c.itemSplit||"lines"===c.itemSplit?i.itemSplit=c.itemSplit:f("invalid-item-split",`Node "${d}": itemSplit "${String(c.itemSplit)}" is not valid (json-array | lines); using json-array.`,d)),!0===c.sequential&&(i.sequential=!0),F(c,i)):e("subflow-map-no-child",`Node "${d}": "mapOverList" needs a single child ("flow" or "subflowSpec") to run once per item.`,d)}if(p&&(!0===c.mapOverList?e("subflow-map-and-parallel-var",`Node "${d}": "parallelFlowsVariable" (dynamic fan-out) cannot be combined with "mapOverList".`,d):i.parallelSubflowIdsVar=p),c.flow){if(h.some(a=>a.toLowerCase()===c.flow.toLowerCase()))return e("subflow-cycle",`Node "${d}": flow "${c.flow}" refers to an ancestor flow, which would create a cycle.`,d);let a=B(c.flow,[...b.flows??[],...n]);return a?i.subflowId=a:e("subflow-unresolved",`Node "${d}": flow "${c.flow}" does not match any existing flow (by id or name).`,d)}if(c.subflowSpec){if(g+1>j)return e("subflow-too-deep",`Node "${d}": nested subflows may not go deeper than ${j} level(s); this inline subflow was not compiled.`,d);if(o>=k)return e("subflow-too-many",`Node "${d}": compiling this inline subflow would exceed the maximum of ${k} flows in one bundle; it was not compiled.`,d);let b=a(c.subflowSpec,g+1,h);return b?i.subflowId=b.id:e("subflow-child-empty",`Node "${d}": the inline "subflowSpec" produced no usable flow.`,d)}if(l){let a=[];for(let f of c.parallelFlows){if("string"!=typeof f||!f){e("parallel-flow-invalid",`Node "${d}": a "parallelFlows" entry is missing or not a string.`,d);continue}if(h.some(a=>a.toLowerCase()===f.toLowerCase())){e("subflow-cycle",`Node "${d}": parallel flow "${f}" refers to an ancestor flow, which would create a cycle.`,d);continue}let c=B(f,[...b.flows??[],...n]);c?a.includes(c)||a.push(c):e("parallel-flow-unresolved",`Node "${d}": parallel flow "${f}" does not match any existing flow (by id or name).`,d)}a.length>0?(i.parallelSubflowIds=a,F(c,i)):e("parallel-empty",`Node "${d}": "parallelFlows" resolved to no runnable lanes.`,d);return}if(m){let b=[];for(let f of c.parallelSubflowSpecs){if(!f||"object"!=typeof f){e("parallel-spec-invalid",`Node "${d}": a "parallelSubflowSpecs" entry is not a FlowSpec object.`,d);continue}if(g+1>j){e("subflow-too-deep",`Node "${d}": nested subflows may not go deeper than ${j} level(s); a parallel inline subflow was not compiled.`,d);continue}if(o>=k){e("subflow-too-many",`Node "${d}": compiling a parallel inline subflow would exceed the maximum of ${k} flows in one bundle; it was not compiled.`,d);continue}let c=a(f,g+1,h);c?b.push(c.id):e("subflow-child-empty",`Node "${d}": a "parallelSubflowSpecs" entry produced no usable flow.`,d)}b.length>0?(i.parallelSubflowIds=b,F(c,i)):e("parallel-empty",`Node "${d}": "parallelSubflowSpecs" produced no runnable lanes.`,d);return}p&&i.parallelSubflowIdsVar?F(c,i):void 0!==c.generateSubflow&&null!==c.generateSubflow?e("subflow-generate-unsupported",`Node "${d}": "generateSubflow" is only available through the AI flow generator. Use "subflowSpec" for deterministic nested authoring, or "flow" to reference an existing flow.`,d):e("subflow-missing-flow",`Node "${d}": subflow nodes need a "flow" (existing flow), a "subflowSpec" (inline child), "parallelFlows"/"parallelSubflowSpecs" (concurrent children), or "generateSubflow".`,d)}(c,d,q,I,m),void 0!==c.inputMode&&(x.has(c.inputMode)?m.inputMode=c.inputMode:f("invalid-input-mode",`Node "${d}": inputMode "${String(c.inputMode)}" is not valid (full-history | latest-message | isolated); omitted.`,d)),void 0!==c.outputMode&&(y.has(c.outputMode)?m.outputMode=c.outputMode:f("invalid-output-mode",`Node "${d}": outputMode "${String(c.outputMode)}" is not valid (steps | final-only); omitted.`,d)),void 0!==r){let{text:a,stripped:b}=A(r);b&&f("pill-stripped",`Node "${d}": binding pills are not supported in generated prompts and were replaced with plain names.`,d),m.promptTemplate=a}"boolean"==typeof c.allowCallerPrompt&&(m.allowCallerPrompt=c.allowCallerPrompt),"boolean"==typeof c.allowCallerFanout&&(m.allowCallerFanout=c.allowCallerFanout),"string"==typeof c.captureVariable&&c.captureVariable.trim()&&(m.captureVariable=c.captureVariable.trim()),"string"==typeof c.captureResource&&c.captureResource.trim()&&(m.captureResource=c.captureResource.trim()),"string"==typeof c.captureKv&&c.captureKv.trim()&&(m.captureKv=c.captureKv.trim())}else if("resource"===l){let a="string"==typeof c.runName?c.runName.trim():"",b="string"==typeof c.server?c.server.trim():"",e="string"==typeof c.uri?c.uri.trim():"";a?(m.scope="run",m.runName=a,(b||e)&&f("resource-both-bindings",`Node "${d}": a resource node is EITHER a run artifact ("runName") or a static MCP resource ("server"+"uri"); kept the run artifact.`,d)):(m.scope="mcp",b&&(m.boundServer=b),e&&(m.uri=e),b&&e?h.has(b)||f("server-unknown",`Node "${d}": MCP server "${b}" is not configured in FLUJO.`,d):f("resource-missing-binding",`Node "${d}": a static resource node needs both "server" and "uri" (or a "runName" for a run artifact).`,d))}else if("signal"===l){let a="string"==typeof c.topic?c.topic.trim():"";a?m.topic=a:f("signal-missing-topic",`Node "${d}": a signal node needs a "topic" to emit.`,d),"string"==typeof c.payloadTemplate&&c.payloadTemplate?m.payloadTemplate=c.payloadTemplate:void 0!==r&&(m.payloadTemplate=r)}let t={id:(0,p.A)(),type:l,position:{x:0,y:0},data:{label:c.label||`${l.charAt(0).toUpperCase()}${l.slice(1)} Node`,type:l,...c.description?{description:c.description}:{},properties:m}};if(J.set(d,t),K.push(t),"process"===l&&Array.isArray(c.servers)){let a=new Set;for(let b of c.servers){let c,e=b?.name;if(!e||"string"!=typeof e){f("server-missing-name",`Node "${d}": a server reference is missing its "name"; skipped.`,d);continue}if(a.has(e))continue;a.add(e),h.has(e)||f("server-unknown",`Node "${d}": MCP server "${e}" is not configured in FLUJO.`,d);let g=i[e];if(Array.isArray(b.tools)){if(c=b.tools.filter(a=>"string"==typeof a&&a),g){let a=c.filter(a=>!g.includes(a));a.length>0&&f("tool-unknown",`Node "${d}": server "${e}" does not report tool(s): ${a.join(", ")}.`,d)}}else c=g?[...g]:[];let j={id:(0,p.A)(),type:"mcp",position:{x:0,y:0},data:{label:e,type:"mcp",properties:{boundServer:e,enabledTools:c}}};K.push(j),L.push({processKey:d,mcpNode:j})}}else"process"!==l&&Array.isArray(c.servers)&&c.servers.length>0&&f("servers-on-non-process",`Node "${d}": only process nodes can have "servers"; ignored.`,d)}if(0===J.size)return e("no-usable-nodes","No usable nodes — the spec must contain at least a start node and one step."),null;let M=[],N=new Set;for(let a of E){let b,c=a?.from,d=a?.to,g=c?J.get(c):void 0,h=d?J.get(d):void 0;if(!g||!h){e("edge-unknown-node",`Edge "${String(c)}" -> "${String(d)}" references a node key that does not exist (or was dropped).`);continue}if(g===h){e("edge-self-loop",`Edge "${c}" -> "${d}": a node cannot connect to itself.`);continue}if("resource"===g.type||"resource"===h.type){if(("resource"!==g.type||"process"!==h.type)&&("process"!==g.type||"resource"!==h.type)){e("resource-edge-invalid",`Edge "${c}" -> "${d}": resource nodes connect only to process nodes.`);continue}a.condition&&f("resource-edge-condition",`Edge "${c}" -> "${d}": conditions do not apply to resource wiring; dropped.`),!0===a.bidirectional&&f("resource-edge-bidirectional",`Edge "${c}" -> "${d}": resource wiring is directional (read vs write); "bidirectional" was ignored — add the opposite edge explicitly if the step both reads and writes.`);let b=`${c}->${d}`;if(N.has(b)){f("edge-duplicate",`Edge "${c}" -> "${d}" appears more than once; kept the first.`);continue}N.add(b),M.push(function(a,b){let c="resource"===a.type?"resource-out":"process-right-resource",d="resource"===b.type?"resource-in":"process-left-resource";return{id:`${a.id}:${c}->${b.id}:${d}`,source:a.id,sourceHandle:c,target:b.id,targetHandle:d,type:"resourceEdge",data:{edgeType:"resource"},animated:!1,markerEnd:{...v},style:{...w}}}(g,h));continue}if("start"===h.type){e("edge-into-start",`Edge "${c}" -> "${d}": nothing may connect INTO a start node.`);continue}if("finish"===g.type){e("edge-out-of-finish",`Edge "${c}" -> "${d}": nothing may connect OUT OF a finish node.`);continue}let i=`${c}->${d}`;if(N.has(i)){f("edge-duplicate",`Edge "${c}" -> "${d}" appears more than once; kept the first.`);continue}N.add(i);let j=!0===a.bidirectional;j&&("start"===g.type||"finish"===h.type)&&(f("bidirectional-illegal",`Edge "${c}" -> "${d}" cannot be bidirectional; downgraded to one-way.`),j=!1);let k=a.condition;k&&"object"==typeof k&&("process"!==g.type?f("edge-condition-non-process",`Edge "${c}" -> "${d}" has a condition but leaves a ${g.type} node; conditions only route from process nodes and were dropped.`):(0,r.C)(k.kind)?"always"===k.kind?b={kind:"always",..."last-message"===k.target?{target:"last-message"}:{},...!0===k.negate?{negate:!0}:{}}:"string"!=typeof k.value||0===k.value.length?f("edge-condition-value",`Edge "${c}" -> "${d}" has a condition with no "value"; the condition was dropped.`):("regex"!==k.kind||(0,r.wM)(k.value)||f("edge-condition-regex",`Edge "${c}" -> "${d}" has a regex condition that does not compile; it is kept but will never match at runtime.`),b={kind:k.kind,value:k.value,..."last-message"===k.target?{target:"last-message"}:{},...!0===k.ignoreCase?{ignoreCase:!0}:{},...!0===k.negate?{negate:!0}:{}}):f("edge-condition-kind",`Edge "${c}" -> "${d}" has an unknown condition kind "${String(k.kind)}"; the condition was dropped.`)),M.push(function(a,b,c,d){let e=`${a.type}-bottom`,f=`${b.type}-top`;return{id:`${a.id}:${e}->${b.id}:${f}`,source:a.id,sourceHandle:e,target:b.id,targetHandle:f,type:"custom",data:{edgeType:"standard",...c?{bidirectional:!0}:{},...d?{condition:d}:{}},animated:!0}}(g,h,j,b))}for(let{processKey:a,mcpNode:b}of L){let c=J.get(a);M.push(function(a,b){let c="process-right-mcp",d="mcp-left";return{id:`${a.id}:${c}->${b.id}:${d}`,source:a.id,sourceHandle:c,target:b.id,targetHandle:d,type:"mcpEdge",data:{edgeType:"mcp"},animated:!1,markerEnd:{...t},markerStart:{...t},style:{...u}}}(c,b))}!function(a,b,c,d,e){let f=new Map;for(let a of c){let b=a.data?.edgeType;"mcp"!==b&&"resource"!==b&&(f.has(a.source)||f.set(a.source,[]),f.get(a.source).push(a.target))}let g=[...b.values()],h=g.filter(a=>"resource"===a.type),i=g.filter(a=>"resource"!==a.type),j=i.filter(a=>"start"===a.type),k=j.length>0?j:i.slice(0,1),l=new Map,m=k.map(a=>({id:a.id,depth:0}));for(let a of m)l.set(a.id,0);for(;m.length;){let{id:a,depth:b}=m.shift();for(let c of f.get(a)??[])l.has(c)||(l.set(c,b+1),m.push({id:c,depth:b+1}))}let n=0;for(let a of l.values())n=Math.max(n,a);for(let a of i)l.has(a.id)||l.set(a.id,n+1);let o=new Map;for(let[a,c]of b)o.set(c.id,a);let p=new Map;for(let a of i){let b=o.get(a.id),c=e&&b?e[b]:void 0;if(c&&"number"==typeof c.x&&"number"==typeof c.y){a.position={x:c.x,y:c.y};continue}let d=l.get(a.id),f=p.get(d)??0;p.set(d,f+1),a.position={x:250+280*f,y:150+170*d}}let q=new Map;for(let{processKey:a,mcpNode:c}of d){let d=b.get(a),e=q.get(a)??0;q.set(a,e+1),c.position={x:d.position.x+320,y:d.position.y+150*e}}let r=new Map(g.map(a=>[a.id,a])),s=new Map,t=0;for(let a of h){let b=o.get(a.id),d=e&&b?e[b]:void 0;if(d&&"number"==typeof d.x&&"number"==typeof d.y){a.position={x:d.x,y:d.y};continue}let f=c.find(b=>b.data?.edgeType==="resource"&&(b.source===a.id||b.target===a.id)),g=f?f.source===a.id?f.target:f.source:void 0,h=g?r.get(g):void 0;if(h){let b=s.get(h.id)??0;s.set(h.id,b+1),a.position={x:h.position.x-320,y:h.position.y+150*b}}else{let b=0;for(let a of i)b=Math.max(b,a.position.y);a.position={x:250+280*t,y:b+170},t++}}}(0,J,M,L,0===q?c.positions:void 0);let O={id:H,name:G,...d?.description?{description:d.description}:{},nodes:K,edges:M};return l.push(O),n.push({id:O.id,name:O.name}),O}(a,0,[]),C=l,D=d;let E=D.filter(a=>"error"===a.severity).length;return{flow:q,flows:C,issues:D,errorCount:E,warningCount:D.length-E};function F(a,b){void 0!==a.concurrencyLimit&&("number"!=typeof a.concurrencyLimit||Number.isNaN(a.concurrencyLimit)?f("invalid-concurrency-limit",`Node "${a.key}": concurrencyLimit "${String(a.concurrencyLimit)}" is not a number; using the runtime default.`,a.key):b.concurrencyLimit=Math.max(1,Math.floor(a.concurrencyLimit))),"string"==typeof a.joinSeparator&&(b.joinSeparator=a.joinSeparator),void 0!==a.errorStrategy&&("fail-fast"===a.errorStrategy||"collect-all"===a.errorStrategy?b.errorStrategy=a.errorStrategy:f("invalid-error-strategy",`Node "${a.key}": errorStrategy "${String(a.errorStrategy)}" is not valid (fail-fast | collect-all); using collect-all.`,a.key))}}(a,d);if(!e.flow)return{success:!1,error:"The spec could not be compiled into a flow",statusCode:422,issues:e.issues.map(a=>({severity:a.severity,code:a.code,message:a.message}))};b.updateFlowId&&(e.flow.id=b.updateFlowId);let f=e.flows.flatMap(a=>(0,C.nC)(a,{models:c.compile.models,servers:c.validatorServers,serverTools:c.compile.serverTools}).issues),g=function(a,b){let c=[...a.map(a=>({severity:a.severity,code:a.code,message:a.message})),...b.issues],d=c.filter(a=>"error"===a.severity).length;return{issues:c,errorCount:d,warningCount:c.length-d,isRunnable:0===d}}(e.issues,{issues:f,errorCount:0,warningCount:0,isRunnable:!0}),h=!1;if(b.save&&0===g.errorCount){for(let a of e.flows)await k.flowService.saveFlow(a);h=!0,H.info(`Compiled and saved ${e.flows.length} flow(s); root "${e.flow.name}" (${e.flow.id})`)}else b.save&&H.info(`Compiled flow "${e.flow.name}" has ${g.errorCount} error(s); NOT saved`);return{success:!0,flow:e.flow,flows:e.flows,validation:g,saved:h}}var J=c(44561),K=c(79111),L=c(34115);let M=(0,i.h)("backend/execution/flow/loadConversationState");async function N(a){try{(0,K.ln)(a)}catch{M.warn("Rejected unsafe conversationId on load",{conversationId:a});return}if(J.FlowExecutor.conversationStates.has(a))return M.debug("Loaded state from memory",{conversationId:a}),J.FlowExecutor.conversationStates.get(a);let b=`conversations/${a}`;try{let c=await (0,K.YM)(b,void 0);if(c)return M.debug("Loaded state from storage",{conversationId:a}),await (0,L.jM)(c),J.FlowExecutor.conversationStates.set(a,c),c}catch(b){M.warn("Error loading conversation state from storage",{conversationId:a,error:b})}}var O=c(96249),P=c(63129),Q=c(51172);let R=`A FlowSpec is a JSON object describing a FLUJO flow semantically — node keys and edges, no coordinates, no ids, no layout:
2
- {
3
- "name": "short_flow_name", // letters/digits/_/- only
4
- "description": "what the flow does",
5
- "nodes": [ ... ],
6
- "edges": [ ... ]
7
- }
8
-
9
- NODE TYPES:
10
- - { "key": "unique_key", "type": "start", "label": "...", "prompt": "system-level instructions for the whole flow" }
11
- - { "key": "...", "type": "process", "label": "...", "description": "what this step does",
12
- "model": "<model id or name from the catalog>",
13
- "prompt": "instructions for this step",
14
- "servers": [ { "name": "<server name>", "tools": ["tool_a"] } ], // optional; omit "tools" to enable all
15
- "inputMode": "full-history" | "latest-message" | "isolated", // optional, default full-history
16
- "isolatedPrompt": "...", // only with inputMode "isolated"
17
- "outputMode": "full-conversation" | "latest-message", // optional, default full-conversation; latest-message hides this step's tool calls/results from later steps (they see only its final response)
18
- "maxTurns": 20, // optional; per-step cap on agentic tool-loop turns (retry-until-done in ONE node). Unset = model/system default (50)
19
- "allowedTools": ["tool_a"], // optional; step-level tool allowlist (independent of servers[].tools)
20
- "captureVariable": "NAME", // optional; save this step's output into a run variable other steps inject with \${var:NAME}
21
- "captureResource": "NAME", // optional; ALSO save this step's output as a tracked run resource other steps inject with \${res:NAME} (see rule 9b)
22
- "captureKv": "NAME", // optional; ALSO save this step's output to a PERSISTENT cross-run key other steps inject with \${kv:NAME} (see rule 9d)
23
- "excludeModelPrompt": true|false, // optional; drop the model's base prompt
24
- "excludeStartNodePrompt": true|false, // optional; drop the start node's prompt for this step
25
- "excludeSystemPrompt": true|false } // optional; drop the workflow/handoff guidance block
26
- - { "key": "...", "type": "subflow", "label": "...",
27
- "flow": "<existing flow name or id>", // reference an EXISTING flow, OR:
28
- "subflowSpec": { ...a nested FlowSpec... }, // define a brand-new child flow INLINE (compiled into its own flow and wired automatically), OR fan out concurrently:
29
- "parallelFlows": ["flow_a", "flow_b"], // run several EXISTING child flows CONCURRENTLY, same input to each, outputs joined; OR:
30
- "parallelSubflowSpecs": [ { ...FlowSpec... } ], // run several INLINE child flows concurrently; OR:
31
- "parallelFlowsVariable": "NAME", // DYNAMIC fan-out (rule 7b): pick the target flows AT RUNTIME from run variable \${var:NAME} (a JSON array of flow ids/names, or newline list); mutually exclusive with mapOverList
32
- "mapOverList": true | false, // optional; run the SINGLE child ("flow"/"subflowSpec") ONCE PER ITEM parsed from the input; mutually exclusive with parallelFlows/parallelSubflowSpecs
33
- "itemSplit": "json-array" | "lines", // optional (mapOverList only), how to split the input into items, default json-array
34
- "sequential": true | false, // optional (mapOverList only), run items one at a time in order instead of concurrently, default false
35
- "concurrencyLimit": 4, // optional (parallel / mapOverList), default 4
36
- "joinSeparator": "\\n\\n---\\n\\n", // optional (parallel / mapOverList), string between joined lane outputs, default "\\n\\n"
37
- "errorStrategy": "collect-all" | "fail-fast", // optional (parallel / mapOverList), default collect-all
38
- "inputMode": "full-history" | "latest-message" | "isolated",
39
- "allowCallerPrompt": true | false, // optional, only with inputMode "isolated"; when true a routing step may pass a "prompt" via its handoff tool that overrides the subflow's "prompt" (default)
40
- "allowCallerFanout": true | false, // optional (subflow); when true a routing step may pass a "parallelFlows" array (+ optional "concurrencyLimit") via its handoff tool to CHOOSE the parallel fan-out set at runtime (rule 7c)
41
- "captureVariable": "NAME", // optional; save the subflow's output into a run variable other steps inject with \${var:NAME}
42
- "captureResource": "NAME", // optional; ALSO save the subflow's output as a tracked run resource (\${res:NAME}, rule 9b)
43
- "captureKv": "NAME", // optional; ALSO save the subflow's output to a PERSISTENT cross-run key (\${kv:NAME}, rule 9d)
44
- "outputMode": "steps" | "final-only" }
45
- - { "key": "...", "type": "finish", "label": "..." }
46
- - { "key": "...", "type": "signal", "label": "...", // fire-and-forget event (rule 11): emits {topic, payload} then passes through unchanged
47
- "topic": "<event topic other flows' triggers listen for>", // REQUIRED — a signal with no topic emits nothing
48
- "payloadTemplate": "event body, may use \${var:NAME}" } // optional; defaults to the node prompt
49
- - { "key": "...", "type": "resource", "label": "...", // OPTIONAL/advanced (rule 9c): a data artifact shown in the graph
50
- "server": "<server name>", "uri": "<resource uri>", // EITHER a static MCP resource…
51
- "runName": "NAME" } // …OR a run artifact steps produce/consume
52
-
53
- EDGES: { "from": "<node key>", "to": "<node key>", "bidirectional": true|false,
54
- "condition": { "kind": "contains"|"regex"|"equals", "value": "...",
55
- "target": "last-assistant"|"last-message", // optional, default last-assistant
56
- "ignoreCase": true|false, "negate": true|false } } // condition optional; process-node edges only
57
-
58
- RULES:
59
- 1. Exactly ONE start node; at least one finish node reachable from it.
60
- 2. Every process node MUST reference a configured model (by id, display name, or name).
61
- 3. A process step uses MCP tools ONLY via its "servers" list — never emit nodes of type "mcp".
62
- 4. Do not embed \${tool:...} or \${resource:...} references in prompts — tools are wired through "servers".
63
- 5. Branching: give a process node multiple outgoing edges; its model decides where to hand off at runtime. "bidirectional": true lets the target hand back to the source (agent <-> agent).
64
- 5b. Deterministic routing: give a process node's outgoing edges a "condition" to route WITHOUT the model — the engine takes the first outgoing edge whose predicate matches the last message (default the step's own last assistant message), and a bare (condition-less) edge is the fallback. Use this for reliable data-driven branches (e.g. output contains "FAIL" -> fix step, else -> publish) instead of relying on a small model to emit a handoff. Only process-node edges may carry a condition. Without any condition on a node, that node keeps model-decided handoff (rule 5). If the model still calls a handoff tool, that wins over the condition.
65
- 6. A subflow node may have only ONE outgoing edge. Give it EITHER a "flow" (naming an existing flow) OR a "subflowSpec" (an inline nested FlowSpec that becomes its own child flow) — not both. A "subflowSpec" may itself contain subflow nodes with their own "subflowSpec" (bounded nesting), so you can author whole multi-level flows in one object.
66
- 7. A subflow node may instead fan out to SEVERAL child flows CONCURRENTLY via "parallelFlows" (existing flows) or "parallelSubflowSpecs" (inline). These are STATIC (fixed at author time): the same input is sent to every lane and their outputs are joined. This is about multiple CHILDREN, not successors — the single-outgoing-edge rule (rule 6) still holds. Prefer "parallelFlows" for large fan-outs.
67
- 7b. For DYNAMIC fan-out — when the set of target flows should be decided AT RUNTIME by an earlier step — use "parallelFlowsVariable": "NAME". An upstream process/subflow node captures a JSON array of flow ids/names (or a newline list) into run variable NAME via "captureVariable": "NAME"; this subflow node then fans out over exactly those flows. Unknown ids and a self-reference are dropped, the count is capped, and a non-empty resolution overrides any static "parallelFlows" (empty falls back to it). Mutually exclusive with "mapOverList". Still one outgoing edge (rule 6).
68
- 7c. For AGENTIC fan-out — when the ROUTING MODEL itself should decide the parallel set at the very moment it hands off — set "allowCallerFanout": true on the target subflow node. Its handoff tool then exposes an optional "parallelFlows" (array of flow ids/names) argument plus an optional "concurrencyLimit"; the model passes them at call time to fan out over exactly those flows. A non-empty caller set overrides "parallelFlows"/"parallelFlowsVariable"; unknown ids and a self-reference are dropped and the count is capped. Mutually exclusive with "mapOverList". Still one outgoing edge (rule 6). Prefer 7b's "parallelFlowsVariable" when an EARLIER step computes the set; use 7c when the DECIDING (routing) step is the one that chooses it.
69
- 8. A subflow node may instead run its SINGLE child flow ONCE PER ITEM via "mapOverList": true. The input is split into items by "itemSplit" ("json-array" default, or "lines"), each item is sent to its own child run, and the per-item outputs are joined (same pool/tuning as parallel). Use "sequential": true to run items in order. Mutually exclusive with "parallelFlows"/"parallelSubflowSpecs".
70
- 9. Named variables (scratchpad): a step can save its output with "captureVariable": "NAME" (process or subflow) and any LATER step injects it with \${var:NAME} inside its "prompt" / "isolatedPrompt" / subflow prompt. This survives "latest-message"/"isolated" scoping, unlike conversation history — use it to carry a todo list, a file path, a diff, or a captured result across steps that don't share history. \${var:NAME} is run-scoped and plaintext; it is DISTINCT from \${global:VAR} (configured secrets/config, resolved only for tool args). Capture a subflow's output on the PARENT subflow node — a variable set inside a child flow is not visible to the parent.
71
- 9b. Run resources (tracked data): "captureResource": "NAME" (process or subflow) ALSO saves the step's output as a run-scoped RESOURCE — an addressable artifact (flujo://run/... URI) with lineage (which step produced it, which steps read it), readable via the built-in "flujo" MCP server. A later step injects it with \${res:NAME} exactly like \${var:NAME}. Prefer "captureVariable" for short strings; use "captureResource" when the output is a large document/report/dataset worth tracking, or when other tools/agents should be able to read it back. Large or binary MCP tool results (screenshots, files) are auto-captured as run resources without any spec field.
72
- 9c. Resource nodes are OPTIONAL/advanced — most flows should not use them; prefer rule 9b's captureResource/\${res:NAME}. Emit one only when the data artifact itself should be VISIBLE in the graph: an edge resource→process means the step READS the artifact (its contents are injected into the step's context); process→resource means the step's output is SAVED to it (run artifacts only, equivalent to captureResource with the node's runName). Resource edges are data wiring, not flow control — they never carry conditions and don't count as a step's successor.
73
- 9d. Persistent state (cross-run): "captureKv": "NAME" (process or subflow) saves the step's output to a PERSISTENT key-value store that SURVIVES ACROSS RUNS, injected by any step with \${kv:NAME}. Unlike \${var:} / \${res:} (discarded when the run ends), \${kv:} is what a long-lived SCHEDULED flow uses to carry a loop counter, a pagination cursor, a last-seen id, or a flag to its NEXT run. By default a key lives on the flow's FOLDER board (flows in the same folder share it); prefix the name to change scope: "flow/NAME" (this flow only) or "global/NAME" (whole instance). Plaintext, never secrets (distinct from \${global:VAR}). A model can also read/update a key mid-run via the built-in "flujo" server's kv_get / kv_set tools.
74
- 10. Keep flows minimal — only the steps the task needs. Write clear, specific prompts and labels; fill "description" on process nodes.
75
- 11. Signals (fire-and-forget events): a "signal" node is a deterministic pass-through that, when the path reaches it, emits an event {topic, payload} onto the flow-run event bus and then continues to its successor unchanged (it never calls a model or touches the conversation). Use it when the flow should notify or kick off ANOTHER flow mid-run — a flow-event trigger configured elsewhere listens for the same "topic" (e.g. "when the review finds blockers, emit a review-blocked signal"). Always give it a "topic" (a signal with no topic emits nothing); "payloadTemplate" is the optional event body and may inject \${var:NAME}. Make emission conditional by putting a conditioned edge (rule 5b) INTO the signal node.`;var S=c(12700),T=c(79861);let U=(0,i.h)("backend/services/mcp/quality/cache"),V="mcp-quality-cache";class W{constructor(a=Date.now()){this.entries={},this.dirty=!1,this.now=a}async load(){try{let a=await (0,K.YM)(V,{entries:{}});this.entries=a?.entries&&"object"==typeof a.entries?a.entries:{}}catch(a){U.warn("Failed to load quality cache; starting empty",a),this.entries={}}}get(a,b){let c=this.entries[`${a}::${b}`];if(c&&!(this.now-c.at>864e5))return c.signal}set(a,b,c){this.entries[`${a}::${b}`]={at:this.now,signal:c},this.dirty=!0}async flush(){let a=!1;for(let[b,c]of Object.entries(this.entries))this.now-c.at>864e5&&(delete this.entries[b],a=!0);if(this.dirty||a)try{await (0,K.VH)(V,{entries:this.entries})}catch(a){U.warn("Failed to persist quality cache",a)}}}function X(a){return!Number.isFinite(a)||a<0?0:a>1?1:a}function Y(a,b){return!Number.isFinite(a)||a<=0?0:!Number.isFinite(b)||b<=1?+(a>0):X(Math.log10(a+1)/Math.log10(b+1))}let Z=(0,i.h)("backend/services/mcp/quality/providers/githubStars"),$="github",_=new Map;function aa(){return d??(process.env.GITHUB_TOKEN||void 0)}function ab(a){let b,c=a.server.repository;if(c?.source&&"github"!==c.source.toLowerCase())return null;var d=c?.url;if(!d)return null;try{b=new URL(d.replace(/^git\+/,""))}catch{return null}if(!/(^|\.)github\.com$/i.test(b.hostname))return null;let e=b.pathname.replace(/\.git$/i,"").split("/").filter(Boolean);return e.length<2?null:`${e[0]}/${e[1]}`.toLowerCase()}async function ac(a,b){let c=new AbortController,d=()=>c.abort();b.addEventListener("abort",d,{once:!0});let e=setTimeout(()=>c.abort(),6e3);try{return await fetch(`https://api.github.com${a}`,{headers:function(){let a={Accept:"application/vnd.github+json","User-Agent":"FLUJO-mcp-quality","X-GitHub-Api-Version":"2022-11-28"},b=aa();return b&&(a.Authorization=`Bearer ${b}`),a}(),signal:c.signal,cache:"no-store"})}catch(b){return Z.warn(`GitHub request failed (${a})`,b instanceof Error?b.message:b),null}finally{clearTimeout(e),b.removeEventListener("abort",d)}}function ad(a){return(403===a.status||429===a.status)&&"0"===a.headers.get("x-ratelimit-remaining")}let ae=(0,i.h)("backend/services/mcp/quality/providers/npmDownloads"),af="npm-downloads",ag=new Map;function ah(a){for(let b of a.server.packages??[])if("npm"===b.registryType&&b.identifier)return b.identifier;return null}function ai(a){return a.startsWith("@")}async function aj(a,b){let c=new AbortController,d=()=>c.abort();b.addEventListener("abort",d,{once:!0});let e=setTimeout(()=>c.abort(),6e3);try{return await fetch(`https://api.npmjs.org${a}`,{signal:c.signal,cache:"no-store"})}catch(b){return ae.warn(`npm request failed (${a})`,b instanceof Error?b.message:b),null}finally{clearTimeout(e),b.removeEventListener("abort",d)}}let ak="registry-status",al=[{id:$,label:"GitHub Stars & Activity",defaultWeight:.5,isApplicable:a=>null!==ab(a),cacheKey:a=>ab(a),async prefetch(a,b,c){let d=`${a??""} mcp`.trim(),e=`/search/repositories?q=${encodeURIComponent(d)}&sort=stars&order=desc&per_page=50`,f=await ac(e,c);if(f&&f.ok)try{for(let a of(await f.json()).items??[])a.full_name&&_.set(a.full_name.toLowerCase(),{stars:"number"==typeof a.stargazers_count?a.stargazers_count:0,pushedAtMs:a.pushed_at?Date.parse(a.pushed_at):null})}catch(a){Z.warn("Failed to parse GitHub search response",a)}else if(f&&ad(f))return void Z.warn("GitHub search rate-limited; ranking will degrade to other providers");if(!aa())return;let g=3;for(let a of b){if(g<=0)break;let b=ab(a);if(!b||_.has(b))continue;g-=1;let d=await ac(`/repos/${b}`,c);if(d){if(ad(d))break;if(d.ok)try{let a=await d.json();_.set(b,{stars:"number"==typeof a.stargazers_count?a.stargazers_count:0,pushedAtMs:a.pushed_at?Date.parse(a.pushed_at):null})}catch{}}}},async fetch(a){let b=ab(a);if(!b)return null;let c=_.get(b);if(!c)return null;let d=Y(c.stars,5e4),e=function(a,b,c=30,d=730){if(!a||!Number.isFinite(a))return 0;let e=(b-a)/864e5;return e<=c?1:e>=d?0:X(1-(e-c)/(d-c))}(c.pushedAtMs,Date.now());return{providerId:$,score:X(.7*d+.3*e),evidence:{repo:b,stars:c.stars,...c.pushedAtMs?{pushedAt:new Date(c.pushedAtMs).toISOString()}:{},starsScore:d,recencyScore:e}}}},{id:af,label:"npm Weekly Downloads",defaultWeight:.35,isApplicable:a=>null!==ah(a),cacheKey:a=>ah(a),async prefetch(a,b,c){let d=b.map(ah).filter(a=>!!a&&!ag.has(a)),e=d.filter(a=>!ai(a)),f=d.filter(ai);for(let a=0;a<e.length;a+=100){let b=e.slice(a,a+100),d=await aj(`/downloads/point/last-week/${b.join(",")}`,c);if(d&&d.ok)try{let a=await d.json();if(1===b.length)"number"==typeof a.downloads&&ag.set(b[0],a.downloads);else for(let c of b){let b=a[c];ag.set(c,b&&"number"==typeof b.downloads?b.downloads:0)}}catch(a){ae.warn("Failed to parse npm bulk downloads response",a)}}for(let a of f){let b=await aj(`/downloads/point/last-week/${a}`,c);if(b&&b.ok)try{let c=await b.json();"number"==typeof c.downloads&&ag.set(a,c.downloads)}catch{}}},async fetch(a){let b=ah(a);if(!b)return null;let c=ag.get(b);return void 0===c?null:{providerId:af,score:Y(c,1e6),evidence:{package:b,weeklyDownloads:c}}}},{id:ak,label:"Registry Status",defaultWeight:.15,isApplicable:a=>!0,cacheKey:()=>null,fetch:async a=>({providerId:ak,score:+("active"===a.verificationStatus),evidence:{status:a.verificationStatus}})}];var am=c(89392);let an=(0,i.h)("backend/services/mcp/quality/settings");function ao(){return{providers:al.map(a=>({id:a.id,enabled:!0,weight:a.defaultWeight})),minScore:0,worksGate:!0}}async function ap(){try{let a=await (0,K.YM)(am.Z.MCP_QUALITY_SETTINGS,ao());return function(a){var b,c;let d=ao(),e=a??{},f=new Map;if(Array.isArray(e.providers))for(let a of e.providers)a&&"string"==typeof a.id&&f.set(a.id,a);return{providers:d.providers.map(a=>{let b=f.get(a.id);return{id:a.id,enabled:"boolean"==typeof b?.enabled?b.enabled:a.enabled,weight:"number"==typeof b?.weight&&Number.isFinite(b.weight)&&b.weight>=0?b.weight:a.weight}}),minScore:(b=e.minScore,c=d.minScore,"number"==typeof b&&Number.isFinite(b)?Math.min(1,Math.max(0,b)):c),worksGate:"boolean"==typeof e.worksGate?e.worksGate:d.worksGate,..."string"==typeof e.githubToken&&e.githubToken.length>0?{githubToken:e.githubToken}:{}}}(a)}catch(a){return an.warn("Failed to load mcpQuality settings; using defaults",a),ao()}}let aq=(0,i.h)("backend/services/mcp/quality/orchestrator");async function ar(a,b){let c=new AbortController,d=setTimeout(()=>c.abort(),b);try{return await a(c.signal)}finally{clearTimeout(d)}}async function as(a,b,c={}){let e=c.topN??10;try{var f;let g=c.settings??await ap(),h=al.filter(a=>(function(a,b){let c=a.providers.find(a=>a.id===b);return!!c?.enabled})(g,a.id));if(0===h.length)return b.map(a=>({candidate:a,score:0,signals:[]}));d=(f=g.githubToken)&&f.length>0?f:void 0;let i=b.slice(0,e),j=b.slice(e),k=new W(c.now??Date.now());await k.load();let l=i.map(()=>[]);for(let b of h){let c=i.map((a,b)=>({c:a,i:b})).filter(({c:a})=>b.isApplicable(a)),d=[],e=[];for(let a of c){let c=b.cacheKey(a.c);if(c){let d=k.get(b.id,c);if(d){e.push({i:a.i,signal:d});continue}}d.push(a)}if(b.prefetch&&d.length>0)try{await ar(c=>b.prefetch(a,d.map(a=>a.c),c),12e3)}catch(a){aq.warn(`Provider "${b.id}" prefetch failed; degrading`,a)}for(let{c:a,i:c}of d)try{let d=await ar(c=>b.fetch(a,c),2e3);if(d){l[c].push(d);let e=b.cacheKey(a);e&&k.set(b.id,e,d)}}catch(c){aq.warn(`Provider "${b.id}" fetch failed for "${a.registryName}"`,c)}for(let{i:a,signal:b}of e)l[a].push(b)}await k.flush();let m=i.map((a,b)=>{let c=l[b],d=new Map(c.map(a=>[a.providerId,a])),e=h.filter(b=>b.isApplicable(a)).map(a=>({providerId:a.id,weight:function(a,b){let c=a.providers.find(a=>a.id===b);return c&&c.enabled?c.weight:0}(g,a.id),score:d.get(a.id)?.score??0})),{score:f}=function(a){let b=0,c=0;for(let d of a){let a=Number.isFinite(d.weight)&&d.weight>0?d.weight:0,e=X(d.score);b+=a,c+=a*e}return{score:b>0?c/b:0,breakdown:a}}(e);return{candidate:a,score:f,signals:c}}).map((a,b)=>({s:a,idx:b})).sort((a,b)=>b.s.score-a.s.score||a.idx-b.idx).map(a=>a.s),n=j.map(a=>({candidate:a,score:0,signals:[]}));return[...m,...n]}catch(a){return aq.warn("enrichAndRank failed; returning unranked candidates",a),b.map(a=>({candidate:a,score:0,signals:[]}))}}let at=(0,i.h)("backend/services/mcp/registryInstall"),au="/v0.1/servers";function av(a){return{registryName:a.server.name,server:a.server,verificationStatus:(0,T.vf)(a)}}async function aw(a,b=8){let c=await ax(a,b);return(await as(a,c.map(av))).map(a=>(function(a,b){let c=(0,T.AH)(a),d=c[0];return{name:a.name,...a.title?{title:a.title}:{},...a.description?{description:a.description}:{},installable:c.length>0,requiredEnv:d?(0,T.jg)(d):[],...b?{quality:function(a){let b=b=>a.signals.find(a=>a.providerId===b)?.evidence,c=b($),d=b(af),e=b(ak);return{score:a.score,..."number"==typeof c?.stars?{stars:c.stars}:{},..."number"==typeof d?.weeklyDownloads?{weeklyDownloads:d.weeklyDownloads}:{},..."string"==typeof e?.status?{status:e.status}:{}}}(b)}:{}}})(a.candidate.server,a))}async function ax(a,b){let c=new URL(S.jD+au);c.searchParams.set("version","latest"),c.searchParams.set("limit",String(Math.min(Math.max(b,1),30))),a&&c.searchParams.set("search",a);let d=await (0,S.Ws)(c,15e3);return Array.isArray(d?.servers)?d.servers:[]}async function ay(a){let b=new URL(S.jD+au);b.searchParams.set("version","latest"),b.searchParams.set("limit","10"),b.searchParams.set("search",a);let c=await (0,S.Ws)(b,15e3),d=Array.isArray(c?.servers)?c.servers:[];return d.find(b=>b.server?.name===a)??d[0]??null}async function az(a,b,c){let d;if(!a||"string"!=typeof a)return{installed:!1,error:"A registry server name is required"};try{d=await ay(a)}catch(a){return{installed:!1,error:`Registry lookup failed: ${a instanceof Error?a.message:String(a)}`}}let e=d?.server??null;if(!e)return{installed:!1,error:`No registry entry found for "${a}"`};let f=(0,T.AH)(e)[0];if(!f)return{installed:!1,error:`"${e.name}" has no install method FLUJO supports (stdio package or HTTP remote)`};let g=(0,T.vf)(d),h=(0,T.O$)(a,e,f,g);if(c?.resolveOnly)return{installed:!1,serverName:h.serverName,plan:h};let i=(0,T.jg)(f,b);if(i.length>0)return{installed:!1,needsEnv:i,plan:h,error:`"${e.name}" requires values for: ${i.join(", ")}`};let j=(0,T.cy)((0,T.Yr)(e,f),b),k=j.name,l=await D.mcpService.loadServerConfigs();if(Array.isArray(l)&&l.some(a=>a.name===k)){at.info(`installRegistryServer: "${k}" already configured; reusing`);let{tools:a,error:b}=await D.mcpService.listServerTools(k);return{installed:!0,alreadyExisted:!0,serverName:k,plan:h,tools:(a??[]).map(a=>({name:a.name,...a.description?{description:a.description}:{}})),...b?{error:b}:{}}}at.info(`installRegistryServer: installing "${e.name}" as "${k}" (${f.kind})`);let m=await D.mcpService.updateServerConfig(k,j);if(!Array.isArray(m)&&m&&"success"in m&&!1===m.success)return{installed:!1,error:`Saving the server failed: ${m.error??"unknown error"}`};let{tools:n,error:o}=await D.mcpService.listServerTools(k),p=(n??[]).map(a=>({name:a.name,...a.description?{description:a.description}:{}}));if((c?.worksGate??(await ap()).worksGate)&&0===p.length){at.warn(`installRegistryServer: "${k}" exposed no tools${o?` (${o})`:""}; rolling back (works-gate)`);try{await D.mcpService.deleteServerConfig(k)}catch(a){at.error(`installRegistryServer: rollback of "${k}" failed`,a)}return{installed:!1,worksGateRejected:!0,serverName:k,plan:h,error:o?`"${e.name}" failed to start: ${o}`:`"${e.name}" connected but exposed no tools — rejected by the works-gate. Try a different server.`}}return{installed:!0,serverName:k,plan:h,tools:p,...o?{error:o}:{}}}async function aA(a,b,c){let d;if(!a||"string"!=typeof a)return{installed:!1,error:"A capability search query is required"};try{d=await ax(a,10)}catch(a){return{installed:!1,error:`Registry lookup failed: ${a instanceof Error?a.message:String(a)}`}}let e=await as(a,d.map(av)),f=await ap(),g=c?.minScore??f.minScore,h=c?.maxAttempts??3,i=[],j=0;for(let a of e){let d=a.candidate.registryName;if(a.score<g){i.push({name:d,score:a.score,reason:`below minScore ${g}`});break}if(0===(0,T.AH)(a.candidate.server).length){i.push({name:d,score:a.score,reason:"no supported install method"});continue}if(j>=h)break;j+=1;let e=await az(d,b,{worksGate:!0});if(c?.onAttempt)try{await c.onAttempt(e.plan,e)}catch(a){at.error("installBestForCapability: onAttempt hook failed",a)}if(e.installed)return{...e,attempts:i};let f=e.needsEnv?.length?`needs env: ${e.needsEnv.join(", ")}`:e.worksGateRejected?"works-gate rejected (no tools / failed to start)":e.error??"install failed";i.push({name:d,score:a.score,reason:f})}return{installed:!1,attempts:i,error:`No working server found for "${a}" among the top ${j} installable candidate(s).`}}let aB={requireConsent:!0,namespaceAllowlist:[],trustBrainStem:!0};function aC(a){let{caller:b,settings:c,registryName:d,allowInstall:e}=a;if("generator"===b)return!0===e?{allowed:!0,reason:"generator-allowinstall",message:"Approved by the per-generation allowInstall opt-in."}:{allowed:!1,reason:"generator-not-allowed",message:"Installing is not allowed in this generation (allowInstall is off)."};if("authoring-tool"===b&&c.trustBrainStem)return{allowed:!0,reason:"brainstem-trusted",message:"Approved: the /mcp-flows authoring tool is trusted (mcpAutoInstall.trustBrainStem)."};if(!c.requireConsent)return{allowed:!0,reason:"consent-disabled",message:"Approved: consent is not required (mcpAutoInstall.requireConsent is off)."};let f=function(a){if("string"!=typeof a)return"";let b=a.indexOf("/");return b>0?a.slice(0,b):""}(d);return""!==f&&c.namespaceAllowlist.includes(f)?{allowed:!0,reason:"namespace-allowlisted",message:`Approved: namespace "${f}" is allowlisted.`}:{allowed:!1,reason:"consent-required",message:"Consent required: review the exact command and arguments, then approve this install (SEP-1024)."}}function aD(a,b,c,d,e){return{at:new Date().toISOString(),caller:b,registryName:a.registryName,resolvedName:a.resolvedName,serverName:a.serverName,transport:a.transport,...a.command?{command:a.command}:{},...a.args?{args:a.args}:{},...a.serverUrl?{serverUrl:a.serverUrl}:{},requiredEnvNames:a.requiredEnvNames,verificationStatus:a.verificationStatus,consent:{allowed:c.allowed,reason:c.reason},installed:d,...e?{error:e}:{}}}let aE=(0,i.h)("backend/services/mcp/autoInstall");async function aF(){try{let a=await (0,K.YM)(am.Z.MCP_AUTO_INSTALL_SETTINGS,aB)??{};return{requireConsent:"boolean"==typeof a.requireConsent?a.requireConsent:aB.requireConsent,namespaceAllowlist:Array.isArray(a.namespaceAllowlist)?a.namespaceAllowlist.filter(a=>"string"==typeof a&&a.length>0):[],trustBrainStem:"boolean"==typeof a.trustBrainStem?a.trustBrainStem:aB.trustBrainStem}}catch(a){return aE.warn("Failed to load mcpAutoInstall settings; using safe defaults",a),{...aB}}}let aG="mcp-install-audit",aH=Promise.resolve();async function aI(){try{return await (0,K.YM)(aG,[])}catch(a){return aE.error("Failed to load MCP install audit log",a),[]}}async function aJ(a){let b=aH.catch(()=>{}).then(async()=>{let b=await aI();b.push(a);let c=b.slice(-300);await (0,K.VH)(aG,c)}).catch(a=>{aE.error("Failed to append MCP install audit entry",a)});aH=b,await b}let aK=(0,i.h)("backend/services/mcp/flowAuthoringTools"),aL=["list_flow_building_blocks","validate_flow_spec","create_flow","search_mcp_marketplace","install_mcp_server","install_best_mcp_server"];function aM(){return{type:"object",properties:{spec:{type:"object",description:"The FlowSpec object (see the tool description for the format)."}},required:["spec"]}}function aN(a,b=!1){return{content:[{type:"text",text:JSON.stringify(a,null,2)}],...b?{isError:!0}:{}}}async function aO(a,b){try{if("list_flow_building_blocks"===a){let a=await G();return aN(a.blocks)}if("search_mcp_marketplace"===a){let a="string"==typeof b?.query?b.query:"",c=await aw(a);return aN(c)}if("install_mcp_server"===a){let a="string"==typeof b?.name?b.name:"",c=b?.env&&"object"==typeof b.env&&!Array.isArray(b.env)?b.env:void 0,d=await az(a,c,{resolveOnly:!0});if(!d.plan)return aN(d,!0);let e=await aF(),f=aC({caller:"authoring-tool",settings:e,registryName:a}),g=(0,T.nO)(d.plan.verificationStatus)?void 0:`Unverified / self-asserted registry entry (status: ${d.plan.verificationStatus}). Registry entries are publisher-asserted — review the command before approving.`;if(await aJ(aD(d.plan,"authoring-tool",f,!1)),!f.allowed)return aN({installed:!1,consentRequired:!0,message:f.message,plan:d.plan,...g?{verificationWarning:g}:{}});let h=await az(a,c);return await aJ(aD(h.plan??d.plan,"authoring-tool",f,h.installed,h.error)),aN({...h,...g?{verificationWarning:g}:{}},!h.installed)}if("install_best_mcp_server"===a){let a="string"==typeof b?.capability?b.capability:"",c=b?.env&&"object"==typeof b.env&&!Array.isArray(b.env)?b.env:void 0;if(!a)return aN({error:'Provide a "capability" search term.'},!0);let d=await aF(),e=aC({caller:"authoring-tool",settings:d,registryName:a});if(!e.allowed){let b=(await aw(a)).find(a=>a.installable),d=b?await az(b.name,c,{resolveOnly:!0}):null;return d?.plan&&await aJ(aD(d.plan,"authoring-tool",e,!1)),aN({installed:!1,consentRequired:!0,message:e.message,...d?.plan?{plan:d.plan}:{}})}let f=await aA(a,c,{onAttempt:async(a,b)=>{a&&await aJ(aD(a,"authoring-tool",e,b.installed,b.error))}}),g=f.installed&&!(0,T.nO)(f.plan?.verificationStatus)?`Installed an unverified / self-asserted registry entry (status: ${f.plan?.verificationStatus}).`:void 0;return aN({...f,...g?{verificationWarning:g}:{}},!f.installed)}if("validate_flow_spec"===a||"create_flow"===a){let c=function(a){let b=a?.spec;if("string"==typeof b)try{return JSON.parse(b)}catch{return null}return b??null}(b);if(!c)return aN({error:'Provide a "spec" argument: a FlowSpec object (or a JSON string of one).'},!0);let d=await I(c,{save:"create_flow"===a});if(!d.success)return aN({error:d.error,issues:d.issues??[]},!0);let e=d.flows.length,f=e>1?` (plus ${e-1} nested subflow flow(s))`:"",g={flowId:d.flow.id,flowName:d.flow.name,nodeCount:d.flow.nodes.length,edgeCount:d.flow.edges.length,...e>1?{flows:d.flows.map(a=>({id:a.id,name:a.name}))}:{},validation:d.validation,..."create_flow"===a?{saved:d.saved,...d.saved?{note:`Flow "${d.flow.name}"${f} was created. It is callable as a tool on this MCP server (after a fresh tools/list) and as model "flow-${d.flow.name}" on the OpenAI-compatible endpoint.`}:{note:"NOT saved: validation found errors. Fix the issues and call create_flow again."}}:{}};return aN(g,"create_flow"===a&&!d.saved)}return aN({error:`Unknown authoring tool: ${a}`},!0)}catch(b){return aK.error("authoringCallTool failed",{toolName:a,err:b}),aN({error:`Authoring tool failed: ${b instanceof Error?b.message:String(b)}`},!0)}}var aP=c(92018);let aQ=(0,i.h)("backend/services/mcp/internalTools");function aR(a,b=!1){return{content:[{type:"text",text:"string"==typeof a?a:JSON.stringify(a,null,2)}],...b?{isError:!0}:{}}}function aS(){return[{name:"list_flow_building_blocks",description:'List everything a FlowSpec may reference in this FLUJO instance: configured models (bind to process steps), MCP servers and their tools (attach via "servers"), and existing flows (usable as subflow targets). Call this before authoring a spec.',inputSchema:{type:"object",properties:{}}},{name:"validate_flow_spec",description:`Compile and validate a FlowSpec WITHOUT saving. Returns the compiled flow's validation result (errors block saving; warnings are advisory) so you can iterate until clean, then call create_flow.
76
-
77
- ${R}`,inputSchema:aM()},{name:"create_flow",description:`Create a new FLUJO flow from a FlowSpec. The spec is compiled deterministically (layout, ids, and wiring are generated for you) and saved ONLY when validation finds zero errors — otherwise the issues are returned to fix. Use list_flow_building_blocks first to see the models, MCP servers/tools, and existing flows you may reference.
78
-
79
- ${R}`,inputSchema:aM()},{name:"search_mcp_marketplace",description:"Search the public MCP server registry for new capabilities (voice, browsing, files, email, vision, …). The registry matches the query against server NAMES only (substring) — use short single terms and try several. Returns name, description, whether FLUJO can install it, and which env vars/keys it would require.",inputSchema:{type:"object",properties:{query:{type:"string",description:"Short search term matched against server names."}},required:["query"]}},{name:"install_mcp_server",description:'Install an MCP server from the public registry (by the exact name returned by search_mcp_marketplace) and connect it — this DOWNLOADS AND RUNS a third-party package on the FLUJO host. Installs are gated by consent (SEP-1024): unless this trusted authoring tool is allowed via the mcpAutoInstall settings (trustBrainStem / requireConsent / namespaceAllowlist), the tool returns the exact resolved command + arguments with consentRequired=true INSTEAD of installing, and the caller must obtain explicit approval. Every attempt is written to an audit log (command, args, env NAMES, verification status — never secret values) before any spawn. Returns the FLUJO server name (reference it in FlowSpec "servers") and the tools it provides, or needsEnv when required keys are missing (supply values via the optional "env" argument), or the resolved plan when consent is required. First install can take minutes (package download).',inputSchema:{type:"object",properties:{name:{type:"string",description:'Exact registry name from search results, e.g. "ai.keenable/web-search".'},env:{type:"object",description:"Optional env var values for the server (e.g. required API keys).",additionalProperties:{type:"string"}}},required:["name"]}},{name:"install_best_mcp_server",description:"Install the BEST WORKING MCP server for a capability, unattended — the recommended way to acquire a capability when you don't already have a specific server name. Searches the registry, RANKS candidates by blended quality (GitHub stars + recent activity, npm weekly downloads, registry status), then installs best→worst until one actually boots and exposes tools (the \"works-gate\"): candidates that need unavailable keys, can't be installed, or start with zero tools are skipped automatically. Same consent/audit rules and third-party-code warning as install_mcp_server. Returns the installed server name + its tools and the list of candidates tried, or needsEnv/consentRequired. Prefer this over search+install for headless self-improvement; use install_mcp_server only when you must pin an exact server.",inputSchema:{type:"object",properties:{capability:{type:"string",description:'Short capability term matched against server names, e.g. "youtube", "email", "browser".'},env:{type:"object",description:"Optional env var values shared across attempted servers (e.g. an API key).",additionalProperties:{type:"string"}}},required:["capability"]}},{name:"execute_flow",description:"Run another FLUJO flow (by name or id) with the given input and return its final output. The run is ephemeral (no chat conversation is created). Use list_flow_building_blocks to see the available flows. Nested runs are limited in depth — a flow cannot recurse through itself indefinitely.",inputSchema:{type:"object",properties:{flow:{type:"string",description:"Flow name or flow id."},input:{type:"string",description:"The message to send to the flow as the user turn."}},required:["flow","input"]}},{name:"read_flow",description:"Read a FLUJO flow's full definition (by name or id): its nodes with their prompts, bound models, attached MCP servers/tools and input/output modes, plus the control and MCP edges. Note this is the COMPILED flow (node ids, not FlowSpec keys) — to change it, author a fresh FlowSpec and call update_flow.",inputSchema:{type:"object",properties:{flow:{type:"string",description:"Flow name or flow id."}},required:["flow"]}},{name:"update_flow",description:"REPLACE an existing FLUJO flow's definition (by name or id) with a newly compiled FlowSpec, keeping the flow's id — so planned executions, subflow nodes and conversations that reference it keep working. The spec format is the same as create_flow/validate_flow_spec (see those tool descriptions); saving is gated on zero validation errors. The replaced definition is archived automatically — list_flow_versions / revert_flow can restore it. Note that manual canvas edits made in the builder are part of what gets replaced. Use read_flow first to see what you are replacing.",inputSchema:{type:"object",properties:{flow:{type:"string",description:"Flow name or flow id of the flow to replace."},spec:{type:"object",description:"The FlowSpec object (see the create_flow tool description for the format)."}},required:["flow","spec"]}},{name:"list_flow_versions",description:"List a flow's archived versions (by name or id), newest first. A version is created automatically whenever the flow's definition is overwritten (builder save, update_flow, revert_flow) and holds the definition that was replaced. Use read_flow_version to inspect one and revert_flow to restore one.",inputSchema:{type:"object",properties:{flow:{type:"string",description:"Flow name or flow id."}},required:["flow"]}},{name:"read_flow_version",description:"Read one archived version of a flow (see list_flow_versions): the full definition it held before it was replaced, in the same format as read_flow.",inputSchema:{type:"object",properties:{flow:{type:"string",description:"Flow name or flow id."},version:{type:"string",description:"The version id (see list_flow_versions)."}},required:["flow","version"]}},{name:"revert_flow",description:"Restore an archived version (see list_flow_versions) as the flow's CURRENT definition. The definition being reverted away from is archived first, so a revert can itself be undone. References by flow id keep working.",inputSchema:{type:"object",properties:{flow:{type:"string",description:"Flow name or flow id."},version:{type:"string",description:"The version id to restore (see list_flow_versions)."}},required:["flow","version"]}},{name:"delete_flow",description:"PERMANENTLY delete a FLUJO flow (by name or id). This cannot be undone — the flow's version history is deleted with it. Verify the target with list_flow_building_blocks first.",inputSchema:{type:"object",properties:{flow:{type:"string",description:"Flow name or flow id."}},required:["flow"]}},{name:"list_mcp_servers",description:"List the MCP servers configured in this FLUJO instance with their transport, enabled/disabled state and live connection status. Config details (env vars, headers, credentials) are never included.",inputSchema:{type:"object",properties:{}}},{name:"list_mcp_server_tools",description:"List the tools of one configured MCP server (name, description, input schema). Use together with call_mcp_tool for servers that are not bound to this flow.",inputSchema:{type:"object",properties:{server:{type:"string",description:"The FLUJO server name (see list_mcp_servers)."}},required:["server"]}},{name:"call_mcp_tool",description:"Call a tool on any configured MCP server by server name + tool name. This lets you use servers that are not bound to the current flow. Check the tool's input schema with list_mcp_server_tools first.",inputSchema:{type:"object",properties:{server:{type:"string",description:"The FLUJO server name."},tool:{type:"string",description:"The tool name on that server."},args:{type:"object",description:"Arguments for the tool (per its input schema)."},timeout:{type:"number",description:"Optional timeout in seconds."}},required:["server","tool"]}},{name:"restart_mcp_server",description:"Force-reconnect a configured MCP server (tears the connection down and rebuilds it). Useful when a server is in an error state after a config or environment change.",inputSchema:{type:"object",properties:{server:{type:"string",description:"The FLUJO server name."}},required:["server"]}},{name:"set_mcp_server_enabled",description:"Enable or disable a configured MCP server. Disabling disconnects it and prevents any further use; enabling connects it.",inputSchema:{type:"object",properties:{server:{type:"string",description:"The FLUJO server name."},enabled:{type:"boolean",description:"true to enable + connect, false to disable + disconnect."}},required:["server","enabled"]}},{name:"list_models",description:"List the models configured in this FLUJO instance (id, name, display name, description, provider, base URL, context window). API keys are never included. Reference models by id or name in FlowSpecs.",inputSchema:{type:"object",properties:{}}},{name:"list_planned_executions",description:"List the planned (scheduled/triggered) executions in this FLUJO instance with their trigger type, enabled state, armed status and last run outcome.",inputSchema:{type:"object",properties:{}}},{name:"run_planned_execution",description:"Fire a planned execution immediately (by id, see list_planned_executions) and return the run record with its output.",inputSchema:{type:"object",properties:{id:{type:"string",description:"The planned execution id."}},required:["id"]}},{name:"update_planned_execution",description:'Modify an existing planned execution (by id or name, see list_planned_executions). Patch any of: "enabled" (turn the schedule on/off), "prompt" (the run prompt), "flowId" (the flow to run — accepts a flow name or id), "cron" (a convenience for the trigger\'s cron pattern — works for schedule / mcp-poll / url-watch triggers) or a full "trigger" object for complete control. Flow-driven cadence changes are clamped to a minimum interval (a runaway every-second schedule is rejected). The webhook secret token is never returned.',inputSchema:{type:"object",properties:{execution:{type:"string",description:"The planned execution id or name."},enabled:{type:"boolean",description:"Enable or disable the execution."},prompt:{type:"string",description:"The run prompt."},flowId:{type:"string",description:"The flow to run — a flow name or id (resolved to the flow id)."},cron:{type:"string",description:"Cron pattern (croner syntax; 6-field form for seconds) for the trigger's schedule. Applies to schedule / mcp-poll / url-watch triggers."},trigger:{type:"object",description:"Full trigger config object (escape hatch for complete control). Prefer the named fields above."}},required:["execution"]}},{name:"create_planned_execution",description:'Create a new planned execution: bind a flow to a trigger so it runs headlessly. Provide "name", "flow" (a flow name or id), an optional "prompt", optional "enabled" (default true), and EITHER a full "trigger" object OR a convenience "cron" (which creates a schedule trigger). Flow-driven cadence is clamped to a minimum interval. A webhook trigger\'s secret token is minted server-side and never returned.',inputSchema:{type:"object",properties:{name:{type:"string",description:"A name for the planned execution."},flow:{type:"string",description:"The flow to run — a flow name or id."},prompt:{type:"string",description:"The run prompt (may be empty)."},enabled:{type:"boolean",description:"Whether to arm the trigger immediately (default true)."},cron:{type:"string",description:'Cron pattern for a schedule trigger (convenience — use "trigger" for other trigger types).'},trigger:{type:"object",description:"Full trigger config object (schedule / webhook / file-watch / mcp-poll / url-watch)."}},required:["name","flow"]}},{name:"delete_planned_execution",description:"Permanently delete a planned execution (by id or name, see list_planned_executions), along with its run history. This cannot be undone.",inputSchema:{type:"object",properties:{execution:{type:"string",description:"The planned execution id or name."}},required:["execution"]}},{name:"list_conversations",description:"List the chat conversations stored in this FLUJO instance (id, title, bound flow, status, created/updated timestamps), newest first. Use read_conversation to get a transcript.",inputSchema:{type:"object",properties:{limit:{type:"number",description:"Optional maximum number of conversations to return (newest first). Default: all."}}}},{name:"read_conversation",description:'Read one chat conversation\'s transcript by conversation id (see list_conversations). Returns the displayed messages: system prompts are excluded, nested subflow steps carry a "depth" marker, assistant tool calls are summarized. Long conversations return only the most recent messages — raise "limit" to get more.',inputSchema:{type:"object",properties:{conversation:{type:"string",description:"The conversation id."},limit:{type:"number",description:"Maximum number of most-recent messages to return (default 50). The total transcript size is capped regardless."}},required:["conversation"]}},{name:"terminal",description:'Run a shell command on the FLUJO host and return its combined stdout/stderr plus exit code. Runs through a shell, so pipes and chained commands (e.g. "npm install && npm run build") work. Use it to install dependencies, build a cloned MCP server, inspect the filesystem, or run diagnostics. Working directory defaults to the FLUJO data directory (where cloned servers live under mcp-servers/); pass "cwd" to run elsewhere. The command is killed if it exceeds the timeout, and very large output is truncated.',inputSchema:{type:"object",properties:{command:{type:"string",description:'The shell command line to execute, e.g. "npm install && npm run build".'},cwd:{type:"string",description:"Optional working directory. Relative paths resolve against the FLUJO data directory. Defaults to the data directory."},timeout:{type:"number",description:"Optional timeout in seconds (default 60, max 600). The command is killed if it runs longer."}},required:["command"]}},{name:"kv_get",description:'Read a value from FLUJO\'s PERSISTENT key-value store (the ${kv:NAME} store) — state that survives ACROSS flow runs (loop counters, cursors, flags). Returns { found, value }. Defaults to the instance-global board; pass "scope" to target another board (e.g. a flow-folder board id). Values are plain strings, never secrets.',inputSchema:{type:"object",properties:{name:{type:"string",description:"The key to read (an identifier: letters, digits, _ and -, not starting with a digit)."},scope:{type:"string",description:'Optional board id to read from. Defaults to "global".'}},required:["name"]}},{name:"kv_set",description:'Write a value to FLUJO\'s PERSISTENT key-value store (the ${kv:NAME} store) — state that survives ACROSS flow runs. Last-write-wins. Defaults to the instance-global board; pass "scope" to target another board. Values are plain strings (never secrets — use ${global:} for those) and are size-capped; an oversized write is refused with { saved:false, skipped }.',inputSchema:{type:"object",properties:{name:{type:"string",description:"The key to write (an identifier: letters, digits, _ and -, not starting with a digit)."},value:{type:"string",description:"The string value to store."},scope:{type:"string",description:'Optional board id to write to. Defaults to "global".'}},required:["name","value"]}}]}async function aT(a){let b=await k.flowService.loadFlows();return b.find(b=>b.id===a)??b.find(b=>b.name===a)}async function aU(a){let b=String(a?.flow??"").trim();if(!b)return aR({error:'Provide "flow": a flow name or id.'},!0);let c=await aT(b);if(!c)return aR({error:`No flow named or with id "${b}". Use list_flow_building_blocks to see the available flows.`},!0);let d=global.__flujo_internal_flow_depth??0;if(d>=4)return aR({error:`execute_flow nesting limit (4) reached — refusing to start "${c.name}" to prevent runaway recursion.`},!0);global.__flujo_internal_flow_depth=d+1;try{let b=await (0,o.runFlow)({flowId:c.id,prompt:String(a?.input??""),mode:"ephemeral",flujo:!0,requireApproval:!1});if(b.flowNotFound)return aR({error:`Flow not found: ${b.flowNotFound.name}`},!0);if("error"===b.status)return aR({error:b.error?.message??"Unknown error during flow execution."},!0);return aR(b.outputText??"")}finally{global.__flujo_internal_flow_depth=d}}async function aV(a){let b=String(a?.flow??"").trim();if(!b)return aR({error:'Provide "flow": a flow name or id.'},!0);let c=await aT(b);if(!c)return aR({error:`No flow named or with id "${b}".`},!0);let d=await k.flowService.deleteFlow(c.id);return d.success?aR({deleted:!0,flowId:c.id,flowName:c.name}):aR({error:d.error??`Failed to delete flow "${c.name}".`},!0)}function aW(a){let b=a.nodes.map(a=>{let{mcpNodes:b,...c}=a.data?.properties??{};return{id:a.id,type:a.type,label:a.data?.label,...a.data?.description?{description:a.data.description}:{},properties:c}}),c=a.edges.map(a=>{let b=a.data;return{from:a.source,to:a.target,type:b?.edgeType==="mcp"?"mcp":b?.edgeType==="resource"?"resource":"control",...b?.bidirectional?{bidirectional:!0}:{}}});return{id:a.id,name:a.name,...a.description?{description:a.description}:{},nodes:b,edges:c}}async function aX(a){let b=String(a?.flow??"").trim();if(!b)return aR({error:'Provide "flow": a flow name or id.'},!0);let c=await aT(b);return c?aR({...aW(c),note:"This is the compiled flow (node ids, not FlowSpec keys). To change it, author a fresh FlowSpec and call update_flow — it replaces the whole definition while keeping this flow id."}):aR({error:`No flow named or with id "${b}". Use list_flow_building_blocks to see the available flows.`},!0)}async function aY(a){let b=String(a?.flow??"").trim();if(!b)return aR({error:'Provide "flow": a flow name or id.'},!0);let c=await aT(b);if(!c)return aR({error:`No flow named or with id "${b}".`},!0);let d=await k.flowService.listFlowVersions(c.id);return aR({flowId:c.id,flowName:c.name,versions:d,...0===d.length?{note:"No archived versions yet — versions appear once the flow's definition is overwritten for the first time."}:{}})}async function aZ(a){let b=String(a?.flow??"").trim(),c=String(a?.version??"").trim();if(!b||!c)return aR({error:'Provide "flow" (name or id) and "version" (see list_flow_versions).'},!0);let d=await aT(b);if(!d)return aR({error:`No flow named or with id "${b}".`},!0);let e=await k.flowService.getFlowVersion(d.id,c);return e?aR({versionId:e.versionId,savedAt:e.savedAt,...aW(e.flow)}):aR({error:`No version "${c}" of flow "${d.name}". Use list_flow_versions to see the archived versions.`},!0)}async function a$(a){let b=String(a?.flow??"").trim(),c=String(a?.version??"").trim();if(!b||!c)return aR({error:'Provide "flow" (name or id) and "version" (see list_flow_versions).'},!0);let d=await aT(b);if(!d)return aR({error:`No flow named or with id "${b}".`},!0);let e=await k.flowService.revertFlow(d.id,c);return e.success?aR({reverted:!0,flowId:d.id,versionId:c,note:"The definition that was just replaced has been archived too, so this revert can itself be undone via list_flow_versions / revert_flow."}):aR({error:e.error??`Failed to revert flow "${d.name}".`},!0)}async function a_(a){let b=String(a?.flow??"").trim();if(!b)return aR({error:'Provide "flow": the name or id of the flow to replace.'},!0);let c=function(a){let b=a?.spec;if("string"==typeof b)try{return JSON.parse(b)}catch{return null}return b??null}(a);if(!c)return aR({error:'Provide a "spec" argument: a FlowSpec object (or a JSON string of one).'},!0);let d=await aT(b);if(!d)return aR({error:`No flow named or with id "${b}". Use list_flow_building_blocks to see the available flows.`},!0);let e=await I(c,{save:!0,updateFlowId:d.id});return e.success?aR({flowId:e.flow.id,flowName:e.flow.name,nodeCount:e.flow.nodes.length,edgeCount:e.flow.edges.length,validation:e.validation,saved:e.saved,...e.saved?{note:`Flow "${e.flow.name}" was replaced (id ${e.flow.id} kept — existing references keep working).`}:{note:"NOT saved: validation found errors. The existing flow is unchanged. Fix the issues and call update_flow again."}},!e.saved):aR({error:e.error,issues:e.issues??[]},!0)}async function a0(a){let b=await a.loadServerConfigs();return Array.isArray(b)?aR(await Promise.all(b.map(async b=>{let c="unknown";try{c=(await a.getServerStatus(b.name)).status}catch(a){aQ.debug(`list_mcp_servers: getServerStatus failed for ${b.name}`,a)}return{name:b.name,transport:b.transport,enabled:!b.disabled,status:c,...b.builtIn?{builtIn:!0}:{}}}))):aR({error:b.error??"Failed to load server configs."},!0)}async function a1(a,b){let c=String(b?.server??"").trim();if(!c)return aR({error:'Provide "server": a FLUJO server name.'},!0);if(c===aP._)return aR(aS().map(a=>({name:a.name,description:a.description,inputSchema:a.inputSchema})));let{tools:d,error:e}=await a.listServerTools(c);return e?aR({error:e},!0):aR(d.map(a=>({name:a.name,description:a.description,inputSchema:a.inputSchema})))}async function a2(a,b){let c=String(b?.server??"").trim(),d=String(b?.tool??"").trim();if(!c||!d)return aR({error:'Provide "server" and "tool".'},!0);if(c===aP._)return aR({error:`"${aP._}" is this server — call its tools directly instead of through call_mcp_tool.`},!0);let e=b?.args&&"object"==typeof b.args&&!Array.isArray(b.args)?b.args:{},f="number"==typeof b?.timeout?b.timeout:void 0,g=await a.callTool(c,d,e,f);if(!g.success)return aR({error:g.error??`Tool call failed on ${c}.`},!0);let h=g.data;return h&&Array.isArray(h.content)?h:aR(h??{ok:!0})}async function a3(a,b){let c=String(b?.server??"").trim();if(!c)return aR({error:'Provide "server": a FLUJO server name.'},!0);if(c===aP._)return aR({ok:!0,note:`"${aP._}" is the built-in server — it is always running.`});let d=await a.forceReconnect(c);if(!d.success)return aR({error:d.error??`Failed to restart ${c}.`},!0);let e=await a.getServerStatus(c);return aR({restarted:!0,server:c,status:e.status})}async function a4(a,b){let c=String(b?.server??"").trim(),d=b?.enabled;if(!c||"boolean"!=typeof d)return aR({error:'Provide "server" (string) and "enabled" (boolean).'},!0);if(c===aP._)return aR({error:`The built-in "${aP._}" server cannot be disabled.`},!0);let e=await a.updateServerConfig(c,{disabled:!d});return"error"in e?aR({error:e.error},!0):aR({server:c,enabled:d})}async function a5(){return aR((await l.modelService.loadModels()).map(a=>({id:a.id,name:a.name,...a.displayName?{displayName:a.displayName}:{},...a.description?{description:a.description}:{},...a.provider?{provider:a.provider}:{},...a.baseUrl?{baseUrl:a.baseUrl}:{},...a.contextWindow?{contextWindow:a.contextWindow}:{}})))}async function a6(){return aR((await (0,m.z)().list()).map(({execution:a,status:b,lastRun:c})=>({id:a.id,name:a.name,enabled:a.enabled,flowId:a.flowId,triggerType:a.trigger?.type,armed:b?.armed??!1,...c?{lastRun:{status:c.status,firedAt:c.firedAt,...c.error?{error:c.error}:{}}}:{}})))}async function a7(a){let b=String(a?.id??"").trim();if(!b)return aR({error:'Provide "id": a planned execution id (see list_planned_executions).'},!0);let{record:c,error:d}=await (0,m.z)().runNow(b);return d||!c?aR({error:d??"Run failed."},!0):aR({runId:c.runId,status:c.status,firedAt:c.firedAt,...c.finishedAt?{finishedAt:c.finishedAt}:{},...c.outputText?{outputText:c.outputText}:{},...c.error?{error:c.error}:{}})}async function a8(a){let b=await (0,m.z)().list(),c=b.find(b=>b.execution.id===a),d=b.find(b=>b.execution.name===a);return(c??d)?.execution??null}function a9(a){return{id:a.id,name:a.name,enabled:a.enabled,flowId:a.flowId,triggerType:a.trigger?.type}}function ba(a,b){try{let c=(0,n.Z9)(a,b,5).map(a=>new Date(a).getTime()),d=1/0;for(let a=1;a<c.length;a++){let b=c[a]-c[a-1];b>0&&b<d&&(d=b)}return Number.isFinite(d)?d:null}catch{return null}}function bb(a){let b=null;return("schedule"===a.type||"url-watch"===a.type?a.cron&&(b=ba(a.cron,a.timezone)):"mcp-poll"===a.type&&(a.cron?b=ba(a.cron,a.timezone):"number"==typeof a.intervalMs&&(b=a.intervalMs)),null!==b&&b<6e4)?`Cadence too fast: the trigger would fire about every ${Math.round(b/1e3)}s, but flow-driven schedule changes are clamped to a minimum interval of 60s. Choose a slower cadence (change it from the Planned Executions page for a faster one).`:null}async function bc(a){let b,c=String(a?.execution??"").trim();if(!c)return aR({error:'Provide "execution": a planned execution id or name (see list_planned_executions).'},!0);let d=await a8(c);if(!d)return aR({error:`No planned execution with id or name "${c}". Use list_planned_executions to see them.`},!0);let e={};"boolean"==typeof a?.enabled&&(e.enabled=a.enabled),"string"==typeof a?.prompt&&(e.prompt=a.prompt);let f=String(a?.flowId??a?.flow??"").trim();if(f){let a=await aT(f);if(!a)return aR({error:`No flow named or with id "${f}". Use list_flow_building_blocks to see the flows.`},!0);e.flowId=a.id}a?.trigger&&"object"==typeof a.trigger&&!Array.isArray(a.trigger)&&(b=a.trigger);let g="string"==typeof a?.cron?a.cron.trim():"";if(g){let a=b??d.trigger;if("schedule"!==a.type&&"mcp-poll"!==a.type&&"url-watch"!==a.type)return aR({error:`The "${a.type}" trigger has no schedule to change with "cron". Pass a full "trigger" object instead.`},!0);b={...a,cron:g}}if(b){let a=bb(b);if(a)return aR({error:a},!0);e.trigger=b}if(0===Object.keys(e).length)return aR({error:"Nothing to update. Provide at least one of: enabled, prompt, flowId, cron, trigger."},!0);let h=await (0,m.z)().update(d.id,e);return h.error||!h.execution?aR({error:h.error??"Update failed."},!0):aR({updated:!0,...a9(h.execution)})}async function bd(a){let b,c=String(a?.name??"").trim();if(!c)return aR({error:'Provide "name": a name for the planned execution.'},!0);let d=String(a?.flow??a?.flowId??"").trim();if(!d)return aR({error:'Provide "flow": a flow name or id to run.'},!0);let e=await aT(d);if(!e)return aR({error:`No flow named or with id "${d}". Use list_flow_building_blocks to see the flows.`},!0);if(a?.trigger&&"object"==typeof a.trigger&&!Array.isArray(a.trigger))b=a.trigger;else{let c="string"==typeof a?.cron?a.cron.trim():"";if(!c)return aR({error:'Provide a "trigger" object or a "cron" pattern (which creates a schedule trigger).'},!0);b={type:"schedule",cron:c}}let f=bb(b);if(f)return aR({error:f},!0);let g={name:c,enabled:"boolean"!=typeof a?.enabled||a.enabled,flowId:e.id,prompt:"string"==typeof a?.prompt?a.prompt:"",trigger:b},h=await (0,m.z)().create(g);return h.error||!h.execution?aR({error:h.error??"Create failed."},!0):aR({created:!0,...a9(h.execution)})}async function be(a){let b=String(a?.execution??"").trim();if(!b)return aR({error:'Provide "execution": a planned execution id or name (see list_planned_executions).'},!0);let c=await a8(b);if(!c)return aR({error:`No planned execution with id or name "${b}". Use list_planned_executions to see them.`},!0);let d=await (0,m.z)().delete(c.id);return d.success?aR({deleted:!0,id:c.id,name:c.name}):aR({error:d.error??`Failed to delete "${c.name}".`},!0)}async function bf(a){let b,c=f().join((0,P.ok)(),"db","conversations");try{b=await g.promises.readdir(c)}catch(a){if("ENOENT"===a.code)return aR([]);return aR({error:`Failed to list conversations: ${a instanceof Error?a.message:String(a)}`},!0)}let d=(await Promise.all(b.filter(a=>a.endsWith(".json")).map(async a=>{try{let b=await g.promises.readFile(f().join(c,a),"utf-8"),d=JSON.parse(b),e=d.conversationId||a.replace(/\.json$/,""),h=d.status;return"running"===h&&0===O.$.currentSeq(e)&&(h="error"),{id:e,title:d.title||"Untitled Conversation",flowId:d.flowId||null,...h?{status:h}:{},createdAt:d.createdAt||0,updatedAt:d.updatedAt||0}}catch(b){return aQ.warn(`list_conversations: skipping unreadable conversation file ${a}`,b),null}}))).filter(a=>null!==a).sort((a,b)=>b.updatedAt-a.updatedAt),e="number"==typeof a?.limit&&a.limit>0?Math.floor(a.limit):void 0;return aR(e?d.slice(0,e):d)}async function bg(a){let b=String(a?.conversation??"").trim();if(!b)return aR({error:'Provide "conversation": a conversation id (see list_conversations).'},!0);await (0,L.u8)(b);let c=await N(b);if(!c)return aR({error:`No conversation with id "${b}". Use list_conversations to see the stored conversations.`},!0);let d=await (0,L.Os)(b),e=d?(0,L.cc)(d):[],f=e.length>0?e:(c.messages||[]).filter(a=>"system"!==a.role),g="number"==typeof a?.limit&&a.limit>0?Math.floor(a.limit):50,h=[],i=0;for(let a=f.length-1;a>=0&&h.length<g;a--){let b=function(a){let b="";"string"==typeof a.content?b=a.content:Array.isArray(a.content)&&(b=a.content.map(a=>"text"in a&&"string"==typeof a.text?a.text:"").filter(Boolean).join("\n"));let c={role:a.role,...b?{content:b}:{},...a.timestamp?{timestamp:a.timestamp}:{},...a.depth?{depth:a.depth}:{}};return"assistant"===a.role&&Array.isArray(a.tool_calls)&&a.tool_calls.length>0&&(c.toolCalls=a.tool_calls.map(a=>{let b="function"in a?a.function:void 0,c=b&&"string"==typeof b.arguments?b.arguments:void 0;return{id:a.id,...b?.name?{name:b.name}:{},...void 0!==c?{arguments:c.length>2e3?c.slice(0,2e3)+"…[truncated]":c}:{}}})),"tool"===a.role&&a.tool_call_id&&(c.toolCallId=a.tool_call_id),c}(f[a]),c=JSON.stringify(b).length;if(h.length>0&&i+c>1e5)break;h.push(b),i+=c}return h.reverse(),aR({id:c.conversationId||b,title:c.title||"Untitled Conversation",flowId:c.flowId||null,...c.status?{status:c.status}:{},createdAt:c.createdAt||0,updatedAt:c.updatedAt||0,totalMessages:f.length,...h.length<f.length?{note:`Returning the ${h.length} most recent of ${f.length} messages — raise "limit" to get more.`}:{},messages:h})}async function bh(a){let b=String(a?.command??"").trim();if(!b)return aR({error:'Provide "command": a shell command line to run.'},!0);let c=(0,P.ok)(),d="string"==typeof a?.cwd?a.cwd.trim():"",e=d?f().isAbsolute(d)?d:f().join(c,d):c,g=Math.min(1e3*("number"==typeof a?.timeout&&a.timeout>0?a.timeout:60),6e5);return await new Promise(a=>{let c,d,f="",i=!1,k=!1,l=!1,m=a=>{!i&&(f+=a).length>1e5&&(f=f.slice(0,1e5)+"\n…[output truncated]",i=!0)},n="win32"!==process.platform;try{c=(0,h.spawn)(b,{cwd:e,shell:!0,env:process.env,detached:n})}catch(b){a(aR({error:`Failed to start command: ${b instanceof Error?b.message:String(b)}`,cwd:e},!0));return}let o=setTimeout(()=>{l=!0,d=function(a,b=2e3){let c=a.pid;if(void 0===c)return()=>{};if("win32"===process.platform){try{(0,h.spawn)("taskkill",["/pid",String(c),"/T","/F"]).on("error",a=>j.debug(`taskkill failed for pid ${c}: ${a.message}`))}catch(a){j.debug(`taskkill spawn threw for pid ${c}: ${a instanceof Error?a.message:String(a)}`)}return()=>{}}try{process.kill(-c,"SIGTERM")}catch{}let d=setTimeout(()=>{try{process.kill(-c,"SIGKILL")}catch{}},b);return d.unref?.(),()=>clearTimeout(d)}(c)},g),p=b=>{k||(k=!0,clearTimeout(o),d?.(),a(b))};c.stdout?.on("data",a=>m(a.toString())),c.stderr?.on("data",a=>m(a.toString())),c.on("error",a=>{m(`
80
- ${a.message}`),p(aR({error:`Command failed to start: ${a.message}`,cwd:e,output:f},!0))}),c.on("close",a=>{if(l)return void p(aR({timedOut:!0,cwd:e,exitCode:a,output:`${f}
81
- [killed after ${g/1e3}s timeout]`},!0));p(aR({exitCode:a,cwd:e,output:f},0!==a))})})}let bi=/^[A-Za-z0-9_-]{1,64}$/,bj=/^[A-Za-z_][\w-]*$/;async function bk(a){let b="string"==typeof a.name?a.name.trim():"",c="string"==typeof a.scope&&a.scope.trim()?a.scope.trim():"global";if(!bj.test(b))return aR({error:'kv_get requires a valid "name" (letters, digits, _ and -, not starting with a digit).'},!0);if(!bi.test(c))return aR({error:`Invalid kv scope id: ${c}`},!0);let d=await (0,Q.M3)(c,b);return aR({scope:c,name:b,found:void 0!==d,value:d??null})}async function bl(a){let b="string"==typeof a.name?a.name.trim():"",c="string"==typeof a.scope&&a.scope.trim()?a.scope.trim():"global",d="string"==typeof a.value?a.value:null==a.value?"":String(a.value);if(!bj.test(b))return aR({error:'kv_set requires a valid "name" (letters, digits, _ and -, not starting with a digit).'},!0);if(!bi.test(c))return aR({error:`Invalid kv scope id: ${c}`},!0);let e=await (0,Q.or)(c,b,d);return"skipped"in e?aR({scope:c,name:b,saved:!1,skipped:e.skipped},!0):aR({scope:c,name:b,saved:!0,size:e.size})}async function bm(a,b,c){try{if(aL.includes(b))return await aO(b,c);switch(b){case"execute_flow":return await aU(c);case"read_flow":return await aX(c);case"update_flow":return await a_(c);case"list_flow_versions":return await aY(c);case"read_flow_version":return await aZ(c);case"revert_flow":return await a$(c);case"delete_flow":return await aV(c);case"list_mcp_servers":return await a0(a);case"list_mcp_server_tools":return await a1(a,c);case"call_mcp_tool":return await a2(a,c);case"restart_mcp_server":return await a3(a,c);case"set_mcp_server_enabled":return await a4(a,c);case"list_models":return await a5();case"list_planned_executions":return await a6();case"run_planned_execution":return await a7(c);case"update_planned_execution":return await bc(c);case"create_planned_execution":return await bd(c);case"delete_planned_execution":return await be(c);case"list_conversations":return await bf(c);case"read_conversation":return await bg(c);case"terminal":return await bh(c);case"kv_get":return await bk(c);case"kv_set":return await bl(c);default:return aR({error:`Unknown tool on the built-in FLUJO server: ${b}`},!0)}}catch(a){return aQ.error("internalCallTool failed",{toolName:b,err:a}),aR({error:`Tool failed: ${a instanceof Error?a.message:String(a)}`},!0)}}}};
@@ -1 +0,0 @@
1
- "use strict";exports.id=6644,exports.ids=[6644],exports.modules={17332:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(27080),e=c(21124);let f=(0,d.A)((0,e.jsx)("path",{d:"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z"}),"ExpandMore")},19925:(a,b,c)=>{c.d(b,{A:()=>n});var d=c(38301),e=c(43249),f=c(2783),g=c(18168),h=c(6636),i=c(29565),j=c(33105);function k(a){return(0,j.Ay)("MuiDialogActions",a)}(0,i.A)("MuiDialogActions",["root","spacing"]);var l=c(21124);let m=(0,g.Ay)("div",{name:"MuiDialogActions",slot:"Root",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[b.root,!c.disableSpacing&&b.spacing]}})({display:"flex",alignItems:"center",padding:8,justifyContent:"flex-end",flex:"0 0 auto",variants:[{props:({ownerState:a})=>!a.disableSpacing,style:{"& > :not(style) ~ :not(style)":{marginLeft:8}}}]}),n=d.forwardRef(function(a,b){let c=(0,h.b)({props:a,name:"MuiDialogActions"}),{className:d,disableSpacing:g=!1,...i}=c,j={...c,disableSpacing:g},n=(a=>{let{classes:b,disableSpacing:c}=a;return(0,f.A)({root:["root",!c&&"spacing"]},k,b)})(j);return(0,l.jsx)(m,{className:(0,e.A)(n.root,d),ownerState:j,ref:b,...i})})},38313:(a,b,c)=>{c.d(b,{A:()=>g,f:()=>f});var d=c(29565),e=c(33105);function f(a){return(0,e.Ay)("MuiListItemIcon",a)}let g=(0,d.A)("MuiListItemIcon",["root","alignItemsFlexStart"])},40512:(a,b,c)=>{c.d(b,{A:()=>B});var d=c(38301),e=c(43249),f=c(2783),g=c(92869),h=c(6638),i=c(6537),j=c(49565),k=c(54573),l=c(29565),m=c(33105);function n(a){return(0,m.Ay)("MuiDialog",a)}let o=(0,l.A)("MuiDialog",["root","scrollPaper","scrollBody","container","paper","paperScrollPaper","paperScrollBody","paperWidthFalse","paperWidthXs","paperWidthSm","paperWidthMd","paperWidthLg","paperWidthXl","paperFullWidth","paperFullScreen"]);var p=c(94842),q=c(65012),r=c(18168),s=c(60839),t=c(68333),u=c(6636),v=c(20385),w=c(21124);let x=(0,r.Ay)(q.A,{name:"MuiDialog",slot:"Backdrop",overrides:(a,b)=>b.backdrop})({zIndex:-1}),y=(0,r.Ay)(i.A,{name:"MuiDialog",slot:"Root",overridesResolver:(a,b)=>b.root})({"@media print":{position:"absolute !important"}}),z=(0,r.Ay)("div",{name:"MuiDialog",slot:"Container",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[b.container,b[`scroll${(0,h.A)(c.scroll)}`]]}})({height:"100%","@media print":{height:"auto"},outline:0,variants:[{props:{scroll:"paper"},style:{display:"flex",justifyContent:"center",alignItems:"center"}},{props:{scroll:"body"},style:{overflowY:"auto",overflowX:"hidden",textAlign:"center","&::after":{content:'""',display:"inline-block",verticalAlign:"middle",height:"100%",width:"0"}}}]}),A=(0,r.Ay)(k.A,{name:"MuiDialog",slot:"Paper",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[b.paper,b[`scrollPaper${(0,h.A)(c.scroll)}`],b[`paperWidth${(0,h.A)(String(c.maxWidth))}`],c.fullWidth&&b.paperFullWidth,c.fullScreen&&b.paperFullScreen]}})((0,t.A)(({theme:a})=>({margin:32,position:"relative",overflowY:"auto","@media print":{overflowY:"visible",boxShadow:"none"},variants:[{props:{scroll:"paper"},style:{display:"flex",flexDirection:"column",maxHeight:"calc(100% - 64px)"}},{props:{scroll:"body"},style:{display:"inline-block",verticalAlign:"middle",textAlign:"initial"}},{props:({ownerState:a})=>!a.maxWidth,style:{maxWidth:"calc(100% - 64px)"}},{props:{maxWidth:"xs"},style:{maxWidth:"px"===a.breakpoints.unit?Math.max(a.breakpoints.values.xs,444):`max(${a.breakpoints.values.xs}${a.breakpoints.unit}, 444px)`,[`&.${o.paperScrollBody}`]:{[a.breakpoints.down(Math.max(a.breakpoints.values.xs,444)+64)]:{maxWidth:"calc(100% - 64px)"}}}},...Object.keys(a.breakpoints.values).filter(a=>"xs"!==a).map(b=>({props:{maxWidth:b},style:{maxWidth:`${a.breakpoints.values[b]}${a.breakpoints.unit}`,[`&.${o.paperScrollBody}`]:{[a.breakpoints.down(a.breakpoints.values[b]+64)]:{maxWidth:"calc(100% - 64px)"}}}})),{props:({ownerState:a})=>a.fullWidth,style:{width:"calc(100% - 64px)"}},{props:({ownerState:a})=>a.fullScreen,style:{margin:0,width:"100%",maxWidth:"100%",height:"100%",maxHeight:"none",borderRadius:0,[`&.${o.paperScrollBody}`]:{margin:0,maxWidth:"100%"}}}]}))),B=d.forwardRef(function(a,b){let c=(0,u.b)({props:a,name:"MuiDialog"}),i=(0,s.A)(),l={enter:i.transitions.duration.enteringScreen,exit:i.transitions.duration.leavingScreen},{"aria-describedby":m,"aria-labelledby":o,"aria-modal":q=!0,BackdropComponent:r,BackdropProps:t,children:B,className:C,disableEscapeKeyDown:D=!1,fullScreen:E=!1,fullWidth:F=!1,maxWidth:G="sm",onBackdropClick:H,onClick:I,onClose:J,open:K,PaperComponent:L=k.A,PaperProps:M={},scroll:N="paper",slots:O={},slotProps:P={},TransitionComponent:Q=j.A,transitionDuration:R=l,TransitionProps:S,...T}=c,U={...c,disableEscapeKeyDown:D,fullScreen:E,fullWidth:F,maxWidth:G,scroll:N},V=(a=>{let{classes:b,scroll:c,maxWidth:d,fullWidth:e,fullScreen:g}=a,i={root:["root"],container:["container",`scroll${(0,h.A)(c)}`],paper:["paper",`paperScroll${(0,h.A)(c)}`,`paperWidth${(0,h.A)(String(d))}`,e&&"paperFullWidth",g&&"paperFullScreen"]};return(0,f.A)(i,n,b)})(U),W=d.useRef(),X=(0,g.A)(o),Y=d.useMemo(()=>({titleId:X}),[X]),Z={slots:{transition:Q,...O},slotProps:{transition:S,paper:M,backdrop:t,...P}},[$,_]=(0,v.A)("root",{elementType:y,shouldForwardComponentProp:!0,externalForwardedProps:Z,ownerState:U,className:(0,e.A)(V.root,C),ref:b}),[aa,ab]=(0,v.A)("backdrop",{elementType:x,shouldForwardComponentProp:!0,externalForwardedProps:Z,ownerState:U}),[ac,ad]=(0,v.A)("paper",{elementType:A,shouldForwardComponentProp:!0,externalForwardedProps:Z,ownerState:U,className:(0,e.A)(V.paper,M.className)}),[ae,af]=(0,v.A)("container",{elementType:z,externalForwardedProps:Z,ownerState:U,className:(0,e.A)(V.container)}),[ag,ah]=(0,v.A)("transition",{elementType:j.A,externalForwardedProps:Z,ownerState:U,additionalProps:{appear:!0,in:K,timeout:R,role:"presentation"}});return(0,w.jsx)($,{closeAfterTransition:!0,slots:{backdrop:aa},slotProps:{backdrop:{transitionDuration:R,as:r,...ab}},disableEscapeKeyDown:D,onClose:J,open:K,onClick:a=>{I&&I(a),W.current&&(W.current=null,H&&H(a),J&&J(a,"backdropClick"))},..._,...T,children:(0,w.jsx)(ag,{...ah,children:(0,w.jsx)(ae,{onMouseDown:a=>{W.current=a.target===a.currentTarget},...af,children:(0,w.jsx)(ac,{as:L,elevation:24,role:"dialog","aria-describedby":m,"aria-labelledby":X,"aria-modal":q,...ad,children:(0,w.jsx)(p.A.Provider,{value:Y,children:B})})})})})})},47902:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(27080),e=c(21124);let f=(0,d.A)((0,e.jsx)("path",{d:"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z"}),"Add")},51791:(a,b,c)=>{c.d(b,{A:()=>g,t:()=>f});var d=c(29565),e=c(33105);function f(a){return(0,e.Ay)("MuiDialogTitle",a)}let g=(0,d.A)("MuiDialogTitle",["root"])},52327:(a,b,c)=>{c.d(b,{A:()=>p});var d=c(38301),e=c(43249),f=c(2783),g=c(18168),h=c(68333),i=c(6636),j=c(29565),k=c(33105);function l(a){return(0,k.Ay)("MuiDialogContent",a)}(0,j.A)("MuiDialogContent",["root","dividers"]);var m=c(51791),n=c(21124);let o=(0,g.Ay)("div",{name:"MuiDialogContent",slot:"Root",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[b.root,c.dividers&&b.dividers]}})((0,h.A)(({theme:a})=>({flex:"1 1 auto",WebkitOverflowScrolling:"touch",overflowY:"auto",padding:"20px 24px",variants:[{props:({ownerState:a})=>a.dividers,style:{padding:"16px 24px",borderTop:`1px solid ${(a.vars||a).palette.divider}`,borderBottom:`1px solid ${(a.vars||a).palette.divider}`}},{props:({ownerState:a})=>!a.dividers,style:{[`.${m.A.root} + &`]:{paddingTop:0}}}]}))),p=d.forwardRef(function(a,b){let c=(0,i.b)({props:a,name:"MuiDialogContent"}),{className:d,dividers:g=!1,...h}=c,j={...c,dividers:g},k=(a=>{let{classes:b,dividers:c}=a;return(0,f.A)({root:["root",c&&"dividers"]},l,b)})(j);return(0,n.jsx)(o,{className:(0,e.A)(k.root,d),ownerState:j,ref:b,...h})})},76345:(a,b,c)=>{c.d(b,{A:()=>g,b:()=>f});var d=c(29565),e=c(33105);function f(a){return(0,e.Ay)("MuiListItemText",a)}let g=(0,d.A)("MuiListItemText",["root","multiline","dense","inset","primary","secondary"])},83899:(a,b,c)=>{c.d(b,{A:()=>n});var d=c(38301),e=c(43249),f=c(2783),g=c(79515),h=c(18168),i=c(6636),j=c(51791),k=c(94842),l=c(21124);let m=(0,h.Ay)(g.default,{name:"MuiDialogTitle",slot:"Root",overridesResolver:(a,b)=>b.root})({padding:"16px 24px",flex:"0 0 auto"}),n=d.forwardRef(function(a,b){let c=(0,i.b)({props:a,name:"MuiDialogTitle"}),{className:g,id:h,...n}=c,o=(a=>{let{classes:b}=a;return(0,f.A)({root:["root"]},j.t,b)})(c),{titleId:p=h}=d.useContext(k.A);return(0,l.jsx)(m,{component:"h2",className:(0,e.A)(o.root,g),ownerState:c,ref:b,variant:"h6",id:h??p,...n})})},91034:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(27080),e=c(21124);let f=(0,d.A)((0,e.jsx)("path",{d:"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6zM19 4h-3.5l-1-1h-5l-1 1H5v2h14z"}),"Delete")},94367:(a,b,c)=>{c.d(b,{A:()=>y});var d=c(38301),e=c(43249),f=c(2783),g=c(37489),h=c(41126),i=c(18168),j=c(68333),k=c(6636),l=c(55470),m=c(14328),n=c(14758),o=c(26636),p=c(93895),q=c(38313),r=c(76345),s=c(29565),t=c(33105);function u(a){return(0,t.Ay)("MuiMenuItem",a)}let v=(0,s.A)("MuiMenuItem",["root","focusVisible","dense","disabled","divider","gutters","selected"]);var w=c(21124);let x=(0,i.Ay)(m.A,{shouldForwardProp:a=>(0,h.A)(a)||"classes"===a,name:"MuiMenuItem",slot:"Root",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[b.root,c.dense&&b.dense,c.divider&&b.divider,!c.disableGutters&&b.gutters]}})((0,j.A)(({theme:a})=>({...a.typography.body1,display:"flex",justifyContent:"flex-start",alignItems:"center",position:"relative",textDecoration:"none",minHeight:48,paddingTop:6,paddingBottom:6,boxSizing:"border-box",whiteSpace:"nowrap","&:hover":{textDecoration:"none",backgroundColor:(a.vars||a).palette.action.hover,"@media (hover: none)":{backgroundColor:"transparent"}},[`&.${v.selected}`]:{backgroundColor:a.vars?`rgba(${a.vars.palette.primary.mainChannel} / ${a.vars.palette.action.selectedOpacity})`:(0,g.X4)(a.palette.primary.main,a.palette.action.selectedOpacity),[`&.${v.focusVisible}`]:{backgroundColor:a.vars?`rgba(${a.vars.palette.primary.mainChannel} / calc(${a.vars.palette.action.selectedOpacity} + ${a.vars.palette.action.focusOpacity}))`:(0,g.X4)(a.palette.primary.main,a.palette.action.selectedOpacity+a.palette.action.focusOpacity)}},[`&.${v.selected}:hover`]:{backgroundColor:a.vars?`rgba(${a.vars.palette.primary.mainChannel} / calc(${a.vars.palette.action.selectedOpacity} + ${a.vars.palette.action.hoverOpacity}))`:(0,g.X4)(a.palette.primary.main,a.palette.action.selectedOpacity+a.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:a.vars?`rgba(${a.vars.palette.primary.mainChannel} / ${a.vars.palette.action.selectedOpacity})`:(0,g.X4)(a.palette.primary.main,a.palette.action.selectedOpacity)}},[`&.${v.focusVisible}`]:{backgroundColor:(a.vars||a).palette.action.focus},[`&.${v.disabled}`]:{opacity:(a.vars||a).palette.action.disabledOpacity},[`& + .${p.A.root}`]:{marginTop:a.spacing(1),marginBottom:a.spacing(1)},[`& + .${p.A.inset}`]:{marginLeft:52},[`& .${r.A.root}`]:{marginTop:0,marginBottom:0},[`& .${r.A.inset}`]:{paddingLeft:36},[`& .${q.A.root}`]:{minWidth:36},variants:[{props:({ownerState:a})=>!a.disableGutters,style:{paddingLeft:16,paddingRight:16}},{props:({ownerState:a})=>a.divider,style:{borderBottom:`1px solid ${(a.vars||a).palette.divider}`,backgroundClip:"padding-box"}},{props:({ownerState:a})=>!a.dense,style:{[a.breakpoints.up("sm")]:{minHeight:"auto"}}},{props:({ownerState:a})=>a.dense,style:{minHeight:32,paddingTop:4,paddingBottom:4,...a.typography.body2,[`& .${q.A.root} svg`]:{fontSize:"1.25rem"}}}]}))),y=d.forwardRef(function(a,b){let c,g=(0,k.b)({props:a,name:"MuiMenuItem"}),{autoFocus:h=!1,component:i="li",dense:j=!1,divider:m=!1,disableGutters:p=!1,focusVisibleClassName:q,role:r="menuitem",tabIndex:s,className:t,...v}=g,y=d.useContext(l.A),z=d.useMemo(()=>({dense:j||y.dense||!1,disableGutters:p}),[y.dense,j,p]),A=d.useRef(null);(0,n.A)(()=>{h&&A.current&&A.current.focus()},[h]);let B={...g,dense:z.dense,divider:m,disableGutters:p},C=(a=>{let{disabled:b,dense:c,divider:d,disableGutters:e,selected:g,classes:h}=a,i=(0,f.A)({root:["root",c&&"dense",b&&"disabled",!e&&"gutters",d&&"divider",g&&"selected"]},u,h);return{...h,...i}})(g),D=(0,o.A)(A,b);return g.disabled||(c=void 0!==s?s:-1),(0,w.jsx)(l.A.Provider,{value:z,children:(0,w.jsx)(x,{ref:D,role:r,tabIndex:c,component:i,focusVisibleClassName:(0,e.A)(C.focusVisible,q),className:(0,e.A)(C.root,t),...v,ownerState:B,classes:C})})})},94842:(a,b,c)=>{c.d(b,{A:()=>d});let d=c(38301).createContext({})},99561:(a,b,c)=>{c.d(b,{A:()=>x});var d=c(38301),e=c(43249),f=c(65823),g=c(74846),h=c(2783),i=c(18168),j=c(60839),k=c(68333),l=c(6636),m=c(29031),n=c(28366),o=c(26636),p=c(29565),q=c(33105);function r(a){return(0,q.Ay)("MuiCollapse",a)}(0,p.A)("MuiCollapse",["root","horizontal","vertical","entered","hidden","wrapper","wrapperInner"]);var s=c(21124);let t=(0,i.Ay)("div",{name:"MuiCollapse",slot:"Root",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[b.root,b[c.orientation],"entered"===c.state&&b.entered,"exited"===c.state&&!c.in&&"0px"===c.collapsedSize&&b.hidden]}})((0,k.A)(({theme:a})=>({height:0,overflow:"hidden",transition:a.transitions.create("height"),variants:[{props:{orientation:"horizontal"},style:{height:"auto",width:0,transition:a.transitions.create("width")}},{props:{state:"entered"},style:{height:"auto",overflow:"visible"}},{props:{state:"entered",orientation:"horizontal"},style:{width:"auto"}},{props:({ownerState:a})=>"exited"===a.state&&!a.in&&"0px"===a.collapsedSize,style:{visibility:"hidden"}}]}))),u=(0,i.Ay)("div",{name:"MuiCollapse",slot:"Wrapper",overridesResolver:(a,b)=>b.wrapper})({display:"flex",width:"100%",variants:[{props:{orientation:"horizontal"},style:{width:"auto",height:"100%"}}]}),v=(0,i.Ay)("div",{name:"MuiCollapse",slot:"WrapperInner",overridesResolver:(a,b)=>b.wrapperInner})({width:"100%",variants:[{props:{orientation:"horizontal"},style:{width:"auto",height:"100%"}}]}),w=d.forwardRef(function(a,b){let c=(0,l.b)({props:a,name:"MuiCollapse"}),{addEndListener:i,children:k,className:p,collapsedSize:q="0px",component:w,easing:x,in:y,onEnter:z,onEntered:A,onEntering:B,onExit:C,onExited:D,onExiting:E,orientation:F="vertical",style:G,timeout:H=m.p0.standard,TransitionComponent:I=f.Ay,...J}=c,K={...c,orientation:F,collapsedSize:q},L=(a=>{let{orientation:b,classes:c}=a,d={root:["root",`${b}`],entered:["entered"],hidden:["hidden"],wrapper:["wrapper",`${b}`],wrapperInner:["wrapperInner",`${b}`]};return(0,h.A)(d,r,c)})(K),M=(0,j.A)(),N=(0,g.A)(),O=d.useRef(null),P=d.useRef(),Q="number"==typeof q?`${q}px`:q,R="horizontal"===F,S=R?"width":"height",T=d.useRef(null),U=(0,o.A)(b,T),V=a=>b=>{if(a){let c=T.current;void 0===b?a(c):a(c,b)}},W=()=>O.current?O.current[R?"clientWidth":"clientHeight"]:0,X=V((a,b)=>{O.current&&R&&(O.current.style.position="absolute"),a.style[S]=Q,z&&z(a,b)}),Y=V((a,b)=>{let c=W();O.current&&R&&(O.current.style.position="");let{duration:d,easing:e}=(0,n.c)({style:G,timeout:H,easing:x},{mode:"enter"});if("auto"===H){let b=M.transitions.getAutoHeightDuration(c);a.style.transitionDuration=`${b}ms`,P.current=b}else a.style.transitionDuration="string"==typeof d?d:`${d}ms`;a.style[S]=`${c}px`,a.style.transitionTimingFunction=e,B&&B(a,b)}),Z=V((a,b)=>{a.style[S]="auto",A&&A(a,b)}),$=V(a=>{a.style[S]=`${W()}px`,C&&C(a)}),_=V(D),aa=V(a=>{let b=W(),{duration:c,easing:d}=(0,n.c)({style:G,timeout:H,easing:x},{mode:"exit"});if("auto"===H){let c=M.transitions.getAutoHeightDuration(b);a.style.transitionDuration=`${c}ms`,P.current=c}else a.style.transitionDuration="string"==typeof c?c:`${c}ms`;a.style[S]=Q,a.style.transitionTimingFunction=d,E&&E(a)});return(0,s.jsx)(I,{in:y,onEnter:X,onEntered:Z,onEntering:Y,onExit:$,onExited:_,onExiting:aa,addEndListener:a=>{"auto"===H&&N.start(P.current||0,a),i&&i(T.current,a)},nodeRef:T,timeout:"auto"===H?null:H,...J,children:(a,{ownerState:b,...c})=>(0,s.jsx)(t,{as:w,className:(0,e.A)(L.root,p,{entered:L.entered,exited:!y&&"0px"===Q&&L.hidden}[a]),style:{[R?"minWidth":"minHeight"]:Q,...G},ref:U,ownerState:{...K,state:a},...c,children:(0,s.jsx)(u,{ownerState:{...K,state:a},className:L.wrapper,ref:O,children:(0,s.jsx)(v,{ownerState:{...K,state:a},className:L.wrapperInner,children:k})})})})});w&&(w.muiSupportAuto=!0);let x=w}};
@@ -1 +0,0 @@
1
- "use strict";exports.id=7427,exports.ids=[7427],exports.modules={21570:(a,b,c)=>{c.d(b,{A:()=>p});var d=c(21124);c(38301);var e=c(40512),f=c(83899),g=c(81637),h=c(79515),i=c(44079),j=c(91059),k=c(52327),l=c(19925),m=c(68730),n=c(30137),o=c(24330);let p=({open:a,onClose:b,title:c,description:p,maxWidth:q="md",...r})=>(0,d.jsxs)(e.A,{open:a,onClose:b,maxWidth:q,fullWidth:!0,children:[(0,d.jsx)(f.A,{component:"div",children:(0,d.jsxs)(g.default,{display:"flex",alignItems:"center",justifyContent:"space-between",children:[(0,d.jsx)(h.default,{variant:"h6",children:c}),(0,d.jsx)(i.A,{edge:"end",color:"inherit",onClick:b,"aria-label":"close",children:(0,d.jsx)(n.A,{})})]})}),(0,d.jsx)(j.A,{}),(0,d.jsxs)(k.A,{sx:{p:3},children:[p&&(0,d.jsx)(h.default,{variant:"body2",color:"text.secondary",sx:{mb:2},children:p}),(0,d.jsx)(o.A,{...r})]}),(0,d.jsx)(l.A,{children:(0,d.jsx)(m.A,{onClick:b,children:"Cancel"})})]})},24330:(a,b,c)=>{c.d(b,{A:()=>o});var d=c(21124),e=c(38301),f=c(82666),g=c(81637),h=c(37674),i=c(67101),j=c(8521),k=c(79515),l=c(40973),m=c(59737);let n={xs:12,sm:6,md:4},o=({isLoading:a=!1,error:b=null,emptyMessage:c="Nothing to choose from.",loadingMessage:o="Loading…",skeleton:p,skeletonCount:q=4,columns:r=n,items:s,searchable:t=!1,searchPlaceholder:u="Search…",searchTerm:v,onSearchChange:w,groups:x,collapsedKeys:y,onToggleGroup:z})=>{let A={...n,...r},[B,C]=(0,e.useState)(""),D=void 0!==v,E=D?v:B,[F,G]=(0,e.useState)(new Set),H=y??F,I=a=>(0,d.jsx)(f.Ay,{container:!0,spacing:2,alignItems:"stretch",children:a.map(a=>(0,d.jsx)(f.Ay,{item:!0,xs:A.xs,sm:A.sm,md:A.md,lg:A.lg,sx:{display:"flex"},children:(0,d.jsx)(g.default,{sx:{width:"100%"},children:a.content})},a.key))}),J=t?(0,d.jsx)(h.A,{placeholder:u,variant:"outlined",size:"small",fullWidth:!0,value:E,onChange:a=>(a=>{w?.(a),D||C(a)})(a.target.value),sx:{mb:2},InputProps:{startAdornment:(0,d.jsx)(i.A,{position:"start",children:(0,d.jsx)(l.A,{fontSize:"small"})})}}):null,K=a=>(0,d.jsxs)(g.default,{children:[J,a]});if(a)return K(p?(0,d.jsx)(f.Ay,{container:!0,spacing:2,children:Array.from({length:q}).map((a,b)=>(0,d.jsx)(f.Ay,{item:!0,xs:A.xs,sm:A.sm,md:A.md,lg:A.lg,children:p},`skeleton-${b}`))}):(0,d.jsxs)(g.default,{sx:{display:"flex",alignItems:"center",gap:1,py:2},children:[(0,d.jsx)(j.default,{size:20}),(0,d.jsx)(k.default,{variant:"body2",color:"text.secondary",children:o})]}));if(b)return K((0,d.jsx)(k.default,{color:"error",variant:"body2",sx:{py:2},children:b}));let L=D?"":E.trim().toLowerCase(),M=a=>!L||(a.searchText??"").toLowerCase().includes(L),N=(0,d.jsx)(k.default,{variant:"body2",color:"text.secondary",sx:{py:2},children:c});if(x){let a=x.map(a=>({...a,items:a.items.filter(M)})).filter(a=>a.items.length>0);return K(0===a.length?N:(0,d.jsx)(d.Fragment,{children:a.map(a=>(0,d.jsx)(m.A,{label:a.label,count:a.items.length,expanded:!H.has(a.key),onToggle:()=>(a=>{if(z)return void z(a);G(b=>{let c=new Set(b);return c.has(a)?c.delete(a):c.add(a),c})})(a.key),children:I(a.items)},a.key))}))}let O=(s??[]).filter(M);return K(0===O.length?N:I(O))}},32640:(a,b,c)=>{c.d(b,{Lg:()=>g,eZ:()=>i,fC:()=>f,h5:()=>j});var d=c(76133),e=c(7329);let f={"name-asc":"Name (A-Z)","name-desc":"Name (Z-A)",provider:"Provider","context-desc":"Context (largest)","context-asc":"Context (smallest)"},g=a=>a.displayName||a.name||"",h=a=>(0,d.T_)(a.provider,a.adapter).label;function i(a,b){switch(b){case"provider":{let b=h(a);return{key:`provider:${b}`,label:b}}case"context-asc":case"context-desc":var c;return"number"!=typeof(c=a.contextWindow)||Number.isNaN(c)?{key:"ctx:unknown",label:"Unknown context"}:c<=8e3?{key:"ctx:<=8k",label:"≤ 8K tokens"}:c<=32e3?{key:"ctx:8k-32k",label:"8K–32K tokens"}:c<=128e3?{key:"ctx:32k-128k",label:"32K–128K tokens"}:c<=1e6?{key:"ctx:128k-1m",label:"128K–1M tokens"}:{key:"ctx:>1m",label:"> 1M tokens"};default:return(0,e.po)(g(a))}}function j(a,b){return[...a].sort((a,c)=>{switch(b){case"name-asc":return g(a).localeCompare(g(c));case"name-desc":return g(c).localeCompare(g(a));case"provider":return h(a).localeCompare(h(c))||g(a).localeCompare(g(c));case"context-desc":case"context-asc":{let d="number"!=typeof a.contextWindow||Number.isNaN(a.contextWindow)?void 0:a.contextWindow,e="number"!=typeof c.contextWindow||Number.isNaN(c.contextWindow)?void 0:c.contextWindow;if(void 0===d&&void 0===e)return g(a).localeCompare(g(c));if(void 0===d)return 1;if(void 0===e)return -1;let f="context-desc"===b?e-d:d-e;return 0!==f?f:g(a).localeCompare(g(c))}default:return 0}})}},45231:(a,b,c)=>{c.d(b,{E:()=>k});var d=c(38301),e=c(2560),f=c(7329),g=c(32640),h=c(61160),i=c(66675);let j={models:{defaultSort:"name-asc",sort:(a,b)=>(0,g.h5)(a,b),deriveSortGroup:(a,b)=>(0,g.eZ)(a,b),getFolder:a=>a.folder,getSearchText:a=>`${(0,g.Lg)(a)} ${a.name??""}`},mcp:{defaultSort:"name-asc",sort:(a,b)=>(0,h.rI)(a,b),deriveSortGroup:(a,b)=>(0,h.mO)(a,b),getFolder:a=>a.folder,getSearchText:a=>`${a.name??""} ${a.rootPath??a.path??""}`},flows:{defaultSort:"name-asc",sort:(a,b)=>(0,i.NP)(a,b),deriveSortGroup:(a,b)=>(0,i.ts)(a,b),getFolder:a=>a.folder,getSearchText:a=>a.name??""}};function k(a,b){let c=j[a],[g,h]=(0,d.useState)(""),[i]=(0,e.Xk)(`flujo-ui:${a}:sort`,c.defaultSort),[k]=(0,e.Xk)(`flujo-ui:${a}:group`,"none"),[l,m]=(0,e.Xk)(`flujo-ui:${a}:collapsed`,[]),n=(0,d.useMemo)(()=>new Set(l),[l]),o=(0,d.useMemo)(()=>{let a=g.trim().toLowerCase(),d=a?b.filter(b=>c.getSearchText(b).toLowerCase().includes(a)):b;return c.sort([...d],i)},[b,g,i,c]),p=(0,d.useMemo)(()=>"folder"===k?(0,f.Je)(o,a=>c.getFolder(a)):"sort"===k?(0,f.Az)(o,a=>c.deriveSortGroup(a,i)):null,[k,o,i,c]);return{searchTerm:g,setSearchTerm:h,sortOption:i,groupMode:k,items:o,groups:p,collapsedKeys:n,toggleGroup:(0,d.useCallback)(a=>{m(b=>b.includes(a)?b.filter(b=>b!==a):[...b,a])},[m])}}},63281:(a,b,c)=>{c.d(b,{g:()=>g});var d=c(2117);let e=(0,c(19815).h)("frontend/services/flow/index");class f{async loadFlows(){e.debug("loadFlows: Entering method");try{if(this.flowsCache)return e.debug("loadFlows: Using cached flows",{count:this.flowsCache.length}),this.flowsCache;let a=await fetch("/api/flow");if(!a.ok){let b=await a.json();throw Error(b.error||"Failed to load flows")}let b=await a.json();return e.debug("loadFlows: Loaded flows from API",{count:b.length}),this.flowsCache=b,b}catch(a){return e.warn("loadFlows: Failed to load flows:",a),[]}}async getFlow(a){e.debug("getFlow: Entering method",{flowId:a});try{if(this.flowsCache){let b=this.flowsCache.find(b=>b.id===a);if(b)return e.debug("getFlow: Using cached flow",{flowId:a}),b}let b=await fetch(`/api/flow/${encodeURIComponent(a)}`);if(!b.ok){if(404===b.status)return e.debug(`getFlow: Flow ${a} not found`),null;let c=await b.json();throw Error(c.error||`Failed to get flow: ${a}`)}let c=await b.json();return e.debug("getFlow: Retrieved flow from API",{flowId:a}),c}catch(b){return e.warn(`getFlow: Failed to get flow ${a}:`,b),null}}async addFlow(a){e.debug("addFlow: Entering method",{flowId:a.id,flowName:a.name,nodeCount:a.nodes.length,edgeCount:a.edges.length});try{let b=await fetch("/api/flow",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!b.ok){let a=await b.json();return{success:!1,error:a.error||"Failed to add flow"}}let c=await b.json();return this.flowsCache&&this.flowsCache.push(c),e.debug("addFlow: Flow added successfully",{flowId:a.id}),{success:!0}}catch(a){return e.warn("addFlow: Failed to add flow:",a),{success:!1,error:a instanceof Error?a.message:"Failed to add flow"}}}async generateFlow(a,b,c){e.debug("generateFlow: Entering method",{modelId:b,allowInstall:c?.allowInstall,allowSubflows:c?.allowSubflows,maxDepth:c?.maxDepth});try{let d=await fetch("/api/flow/generate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({description:a,modelId:b,allowInstall:c?.allowInstall===!0,allowSubflows:c?.allowSubflows===!0,..."number"==typeof c?.maxDepth?{maxDepth:c.maxDepth}:{}})}),f=await d.json().catch(()=>null);if(!d.ok)return{success:!1,error:f?.error||"Failed to generate flow"};let g=Array.isArray(f.flows)&&f.flows.length>0?f.flows:[{flow:f.flow,validation:f.validation}];return e.debug("generateFlow: Draft generated",{flowId:f.flow?.id,flowCount:g.length,attempts:f.attempts,errorCount:f.validation?.errorCount,installedServers:f.installedServers?.length??0}),{success:!0,flow:f.flow,validation:f.validation,flows:g,rootFlowId:f.rootFlowId??f.flow?.id,attempts:f.attempts,installedServers:f.installedServers??[]}}catch(a){return e.warn("generateFlow: Failed to generate flow:",a),{success:!1,error:a instanceof Error?a.message:"Failed to generate flow"}}}async improveFlow(a,b,c,d){e.debug("improveFlow: Entering method",{flowId:a?.id,modelId:c,allowInstall:d?.allowInstall});try{let f=await fetch("/api/flow/improve",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({flow:a,description:b,modelId:c,allowInstall:d?.allowInstall===!0})}),g=await f.json().catch(()=>null);if(!f.ok)return{success:!1,error:g?.error||"Failed to improve flow"};return e.debug("improveFlow: Draft revised",{flowId:g.flow?.id,attempts:g.attempts,errorCount:g.validation?.errorCount,installedServers:g.installedServers?.length??0}),{success:!0,flow:g.flow,validation:g.validation,attempts:g.attempts,installedServers:g.installedServers??[]}}catch(a){return e.warn("improveFlow: Failed to improve flow:",a),{success:!1,error:a instanceof Error?a.message:"Failed to improve flow"}}}async updateFlow(a){e.debug("updateFlow: Entering method",{flowId:a.id,flowName:a.name,nodeCount:a.nodes.length,edgeCount:a.edges.length});try{let b=await fetch(`/api/flow/${encodeURIComponent(a.id)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!b.ok){let a=await b.json();return{success:!1,error:a.error||"Failed to update flow"}}let c=await b.json();if(this.flowsCache){let b=this.flowsCache.findIndex(b=>b.id===a.id);b>=0?this.flowsCache[b]=c:this.flowsCache.push(c)}return e.debug("updateFlow: Flow updated successfully",{flowId:a.id}),{success:!0}}catch(a){return e.warn("updateFlow: Failed to update flow:",a),{success:!1,error:a instanceof Error?a.message:"Failed to update flow"}}}async deleteFlow(a){e.debug("deleteFlow: Entering method",{flowId:a});try{let b=await fetch(`/api/flow/${encodeURIComponent(a)}`,{method:"DELETE"});if(!b.ok){let a=await b.json();return{success:!1,error:a.error||"Failed to delete flow"}}return this.flowsCache&&(this.flowsCache=this.flowsCache.filter(b=>b.id!==a)),e.debug("deleteFlow: Flow deleted successfully",{flowId:a}),{success:!0}}catch(a){return e.warn("deleteFlow: Failed to delete flow:",a),{success:!1,error:a instanceof Error?a.message:"Failed to delete flow"}}}createNode(a,b){return e.debug("createNode: Entering method",{type:a,position:b}),{id:(0,d.A)(),type:a,position:b,data:{label:`${"mcp"===a?"MCP":a.charAt(0).toUpperCase()+a.slice(1)} Node`,type:a,properties:{}}}}createStartNode(){return{id:(0,d.A)(),type:"start",position:{x:250,y:150},data:{label:"Start Node",type:"start",properties:{promptTemplate:""}}}}createNewFlow(a="NewFlow"){e.debug("createNewFlow: Entering method",{name:a});let b=Date.now();return{id:(0,d.A)(),name:a,createdAt:b,updatedAt:b,nodes:[this.createStartNode()],edges:[]}}createHistoryEntry(a,b){return e.debug("createHistoryEntry: Entering method"),{nodes:[...a],edges:[...b]}}generateSampleFlow(a="Sample Flow"){return e.debug("generateSampleFlow: Entering method",{name:a}),{id:(0,d.A)(),name:a,nodes:[{id:"1",type:"start",position:{x:250,y:50},data:{label:"Start Node",type:"start",properties:{prompt:"Enter your query here",systemMessage:"You are a helpful assistant",temperature:0}}},{id:"2",type:"process",position:{x:250,y:200},data:{label:"Process Node",type:"process",properties:{operation:"transform",enabled:!0}}},{id:"3",type:"finish",position:{x:250,y:350},data:{label:"Finish Node",type:"finish",properties:{format:"json",template:'{ "result": {{data}} }'}}},{id:"4",type:"mcp",position:{x:450,y:200},data:{label:"MCP Node",type:"mcp",properties:{channels:2,mode:"parallel"}}}],edges:[{id:"e1-2",source:"1",target:"2",type:"custom"},{id:"e2-3",source:"2",target:"3",type:"custom"}]}}constructor(){this.flowsCache=null}}let g=new f},63908:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(27080),e=c(21124);let f=(0,d.A)((0,e.jsx)("path",{d:"m12 8-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"}),"ExpandLess")},66675:(a,b,c)=>{c.d(b,{NP:()=>h,ts:()=>f});var d=c(7329);function e(a){return a.updatedAt??a.createdAt??0}function f(a,b){switch(b){case"name-asc":case"name-desc":return(0,d.po)(a.name);case"most-nodes":case"least-nodes":var c;return 0===(c=a.nodes.length)?{key:"nodes:0",label:"0 nodes"}:c<=2?{key:"nodes:1-2",label:"1–2 nodes"}:c<=5?{key:"nodes:3-5",label:"3–5 nodes"}:c<=10?{key:"nodes:6-10",label:"6–10 nodes"}:{key:"nodes:11+",label:"11+ nodes"};case"newest":case"oldest":return function(a,b=Date.now()){if(!a)return{key:"recency:unknown",label:"No date"};let c=b-a;return c<864e5?{key:"recency:today",label:"Today"}:c<6048e5?{key:"recency:week",label:"This week"}:c<2592e6?{key:"recency:month",label:"This month"}:{key:"recency:older",label:"Older"}}(e(a));default:return{key:"all",label:"All flows"}}}function g(a,b){return a.name.localeCompare(b.name)||a.id.localeCompare(b.id)}function h(a,b){let c=(a,c)=>{switch(b){case"name-asc":return a.name.localeCompare(c.name);case"name-desc":return c.name.localeCompare(a.name);case"most-nodes":return c.nodes.length-a.nodes.length;case"least-nodes":return a.nodes.length-c.nodes.length;case"newest":{let b=e(c)-e(a);return 0!==b?b:g(a,c)}case"oldest":{let b=e(a)-e(c);return 0!==b?b:g(a,c)}default:return 0}};return[...a].sort((a,b)=>{let d=Number(!!b.favorite)-Number(!!a.favorite);return 0!==d?d:c(a,b)})}},76133:(a,b,c)=>{c.d(b,{T_:()=>e,xx:()=>d});let d=[{id:"openai",label:"OpenAI",provider:"openai",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://api.openai.com/v1",showBaseUrl:!0},{id:"openrouter",label:"OpenRouter",provider:"openrouter",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://openrouter.ai/api/v1",showBaseUrl:!0},{id:"requesty",label:"Requesty",provider:"requesty",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://router.requesty.ai/v1",showBaseUrl:!0},{id:"xai",label:"X.ai",provider:"xai",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://api.x.ai/v1",showBaseUrl:!0},{id:"ollama",label:"Ollama",provider:"ollama",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"http://localhost:11434/v1",showBaseUrl:!0},{id:"litellm",label:"LiteLLM",provider:"litellm",adapter:"openai",sdkLabel:"OpenAI SDK (via LiteLLM Proxy)",baseUrl:"http://localhost:4000/v1",showBaseUrl:!0},{id:"gemini-openai",label:"Gemini (OpenAI Format)",provider:"gemini",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://generativelanguage.googleapis.com/v1beta/openai/",showBaseUrl:!0},{id:"gemini-native",label:"Gemini (Native)",provider:"gemini",adapter:"gemini",sdkLabel:"GenAI SDK",baseUrl:"",showBaseUrl:!1,defaultModels:["gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.0-flash"]},{id:"anthropic-openai",label:"Anthropic (OpenAI Format)",provider:"anthropic",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://api.anthropic.com/v1/",showBaseUrl:!0},{id:"anthropic-native",label:"Anthropic (Native)",provider:"anthropic",adapter:"anthropic",sdkLabel:"Anthropic SDK",baseUrl:"",showBaseUrl:!1,defaultModels:["claude-opus-4-8","claude-sonnet-4-6","claude-haiku-4-5-20251001","claude-fable-5"]},{id:"claude-subscription",label:"Claude Subscription",provider:"claude-subscription",adapter:"claude-cli",sdkLabel:"Claude CLI",baseUrl:"",showBaseUrl:!1,defaultModels:["opus","sonnet","haiku","fable"]}];function e(a,b){let c=a||"openai",e=b||"openai";return d.find(a=>a.provider===c&&a.adapter===e)||d.find(a=>a.provider===c)||d[0]}}};